Code:
package com.dhareauxk;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.swing.JFrame;
import com.dhareauxk.input.KeyController;
import com.dhareauxk.input.MouseController;
import com.dhareauxk.model.Entity;
import com.dhareauxk.model.Npc;
import com.dhareauxk.model.Player;
public class Game extends Canvas implements Runnable {
private static final long serialVersionUID = 1L;
// Rendering related variables
private int averageFrameCount;
private Graphics2D graphics;
private int applicationState = 0;
// Fps variables
private int ONE_SECOND_IN_NANO = 1000 * 1000 * 1000;;
private int reqFps = 120;
private int secondsRunning;
// Spawn local player
private List<Entity> entities = new CopyOnWriteArrayList<Entity>();
private final Player localPlayer = new Player(0, "user", 100, 100);
private final Npc anNpc = new Npc(1, "tux", 100, 100);
long period = ONE_SECOND_IN_NANO / reqFps;
public static void main(String args[]) {
System.out.println("Initializing 2D client..");
new Thread(new Game()).start();
}
public Game() {
JFrame frame = new JFrame(); // Create a JFrame to put the canvas on
frame.setTitle(Config.FRAME_TITLE);
frame.setSize(Config.FRAME_WIDTH, Config.FRAME_HEIGHT);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(this);
frame.setResizable(false);
// Show the frame
frame.validate();
frame.pack();
frame.setVisible(true);
frame.toFront();
// Update the dimensions of the window to allot for the overlap
// prevention
final Insets insets = frame.getInsets();
frame.setSize(Config.FRAME_WIDTH + insets.left + insets.right, Config.FRAME_HEIGHT + insets.top + insets.bottom);
// Set up double buffering
createBufferStrategy(2);
this.graphics = (Graphics2D) super.getGraphics(); // XXX should be
// right..
// Add the mouse mapper to the canvas.
addMouseListener(MouseController.MAPPER);
addMouseMotionListener(MouseController.MAPPER);
// Add the key mapper to the canvas.
addKeyListener(new KeyController(this));
requestFocus();
// Initialize entities
entities.add(localPlayer);
entities.add(anNpc);
}
private int totalFrameCount;
@Override
public void run() {
long
endTime = 0L,
timeDiff = 0L,
startTime = 0L,
sleepTime = 0L,
overSleepTime = 0L;
long previousSampleTime = System.nanoTime();
while (Cache.getInstance().loaded) {
startTime = System.nanoTime(); // cycle start time
update(); // UPDATING before rendering
render(); // Core rendering method
endTime = System.nanoTime();//end time :)
timeDiff = endTime - startTime;//how much cycle takes?
sleepTime = (period - timeDiff) - overSleepTime;
if(sleepTime > 0){
try {
Thread.sleep(sleepTime/(ONE_SECOND_IN_NANO/1000));//we are sleeping here so no more eating processor
} catch(final InterruptedException ignore){//^^ Ignore this
Thread.currentThread().interrupt();
break;
}
overSleepTime = (System.nanoTime() - endTime) - sleepTime;
}else{
overSleepTime = 0L;
}
totalFrameCount++;
if(System.nanoTime() - previousSampleTime > ONE_SECOND_IN_NANO){//passed one second
secondsRunning++;
averageFrameCount = totalFrameCount/secondsRunning;
previousSampleTime = System.nanoTime();
}
}
}
// Update game logic here.
private void update() {
handleMouseInput();
}
private void render() {
if (getBufferStrategy() == null) {
createBufferStrategy(3);
return;
}
graphics = (Graphics2D) getBufferStrategy().getDrawGraphics();
// Clear the screen
graphics.setColor(Color.BLACK);
graphics.fillRect(0, 0, super.getWidth(), super.getHeight());
switch (applicationState) {
case 0: // login state
graphics.setColor(Color.GREEN);
graphics.drawString("Press Enter to Play!", 100, 100);
break;
case 1: // game state
render2DWorld(graphics);
break;
}
// Debug hud
graphics.setColor(Color.BLUE);
graphics.drawString("Used memory: " + ((Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) >> 20) + "MB", 5, 15);
graphics.drawString("FPS: " + averageFrameCount, 5, 30);
graphics.dispose();
// Show the graphics.
getBufferStrategy().show();
Toolkit.getDefaultToolkit().sync();
}
private void render2DWorld(Graphics2D graphics2) {
// Draw "map"
for (int x = 0; x < 10; x++) {
for (int y = 0; y < 8; y++) {
graphics.drawImage(Cache.getInstance().getSprite("tile"), x * 32, y * 32, null); // 32
// =
// tile
// size
}
}
// Draw entities
graphics.drawImage(localPlayer.getSprite(), localPlayer.getX(), localPlayer.getY(), null);
graphics.drawImage(anNpc.getSprite(), anNpc.getX(), anNpc.getY(), null);
// Draw "ui"
graphics.setColor(Color.WHITE);
graphics.fillRect(0, 0, Config.FRAME_WIDTH, 36);
graphics.setColor(Color.BLACK);
graphics.drawRect(0, 0, Config.FRAME_WIDTH, 36);
// The icons..
graphics.drawImage(Cache.getInstance().getSprite("door"), 300, 7, null);
graphics.drawImage(Cache.getInstance().getSprite("information"), 280, 7, null);
}
// Handle key input here
public void handleKeyboardInput(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
System.out.println("Application terminated by user.");
Runtime.getRuntime().exit(0);
}
switch (applicationState) {
case 0: // login
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
applicationState = 1;
}
break;
case 1: // game
if (e.getKeyCode() == KeyEvent.VK_M) {
localPlayer.setSprite("user");
}
if (e.getKeyCode() == KeyEvent.VK_F) {
localPlayer.setSprite("user_female");
}
if (e.getKeyCode() == KeyEvent.VK_UP) {
localPlayer.move(0, -5);
}
if (e.getKeyCode() == KeyEvent.VK_DOWN) {
localPlayer.move(0, 5);
}
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
localPlayer.move(-5, 0);
}
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
localPlayer.move(5, 0);
}
break;
}
}
public void handleMouseInput() {
if (MouseController.isButtonDown(0)) {
// Handle left click
System.out.println("Left cliked @ " + MouseController.getX() + ":" + MouseController.getY());
if (MouseController.getX() >= 283 && MouseController.getY() <= 293) {
if (MouseController.getY() >= 8 && MouseController.getY() <= 19) {
// TODO info button
}
}
if (MouseController.getX() >= 302 && MouseController.getY() <= 312) {
if (MouseController.getY() >= 10 && MouseController.getY() <= 21) {
// TODO info button
}
}
}
if (MouseController.isButtonDown(1)) {
// Handle right click
}
}
}