TFGGame/src/tfg/Game.java

169 lines
4.5 KiB
Java

package tfg;
import org.jsfml.graphics.Color;
import org.jsfml.graphics.RenderWindow;
import org.jsfml.graphics.TextStyle;
import org.jsfml.system.Clock;
import org.jsfml.system.Vector2i;
import org.jsfml.window.Keyboard;
import org.jsfml.window.Keyboard.Key;
import org.jsfml.window.VideoMode;
import org.jsfml.window.event.Event;
/**
* TFG Game's main class.
* This class ideally should be as short as possible.
* @author Ritchie Cunningham
*/
public class Game {
/**
* Main window where everything will be rendered to and handle input.
*/
private RenderWindow window = new RenderWindow();
/**
* Set's the window title.
*/
private final String windowTitle = "TFG Game";
/**
* Set dimensions (resolution) the window is created with.
*/
private final Vector2i windowDimensions = new Vector2i(640, 480);
/**
* Main object representing the player.
*/
private Player player = new Player();
/**
* UI Element responsible for displaying the FPS.
*/
private final TextUIElement fpsUI =
new TextUIElement(InterfacePosition.TOP_LEFT, Color.YELLOW,24,TextStyle.BOLD);
/**
* Repesents whether or not the user has the window opened and in focus.
*/
private boolean windowFocus = true;
/**
* Allows the window to shift focus.
*/
private Camera camera;
/**
* Create an instance of the game and run it.
* @param args Command line arguments passed in at run-time.
*/
public static void main(String[] args) {
Game g = new Game(); /* Create temp object of self. */
g.run(); /* Invoke run. */
}
/**
* Configure one-time settings at start-up.
*/
public void handleInitialization() {
window.create(new VideoMode(windowDimensions.x, windowDimensions.y),
windowTitle);
player.changeMap(new Map(10, 10, Tile.SAND));
camera = new Camera(window);
// window.setFramerateLimit(60);
}
/**
* Initializes the game and holds the main loop.
*/
public void run() {
handleInitialization();
int framesDrawn = 0; /* Count each frame that is rendered */
float updateRate = 20.0f; /* Limit the logic loop to update at 20hz */
Clock updateClock = new Clock(); /* Clock used to restrict update loop rate */
Clock frameClock = new Clock(); /* Used to calc average FPS. */
updateClock.restart(); /* Reset update clock. */
/* Calc next update time in millisecs. */
long nextUpdate = updateClock.getElapsedTime().asMilliseconds();
/* As long as window is open, run main loop. */
while(window.isOpen()) {
handleInput();
/* Make note of the current update time. */
long updateTime = updateClock.getElapsedTime().asMicroseconds();
while ((updateTime-nextUpdate) >= updateRate) {
handleLogic();
nextUpdate += updateRate; /* Compute next appropriate update time. */
}
handleDrawing();
framesDrawn++; // Frame has rendered, increment.
/* How long has it been since last calulating FPS? */
float elapsedTime = frameClock.getElapsedTime().asSeconds();
if(elapsedTime >= 1.0f) { /* If one second */
/* Divide the frames rendered by one second. */
fpsUI.updateString("FPS: " + (int) (framesDrawn/elapsedTime));
framesDrawn = 0; /* Reset the count. */
frameClock.restart(); /* Reset the frame clock. */
}
}
}
public void handleInput() {
/*
* Window based event queue.
* Good for single-press actions, not for repeated actions though.
*/
for(Event event : window.pollEvents()) {
switch(event.type) {
case CLOSED:
window.close();
break;
case GAINED_FOCUS:
windowFocus = true;
break;
case LOST_FOCUS:
windowFocus = false;
default:
break;
}
}
/*
* Real-time input.
* Good for repeated actions, bad for single-press actions.
*/
if(windowFocus) {
if(Keyboard.isKeyPressed(Key.W)) {
player.move(Direction.NORTH);
} else if(Keyboard.isKeyPressed(Key.S)) {
player.move(Direction.SOUTH);
} else if(Keyboard.isKeyPressed(Key.A)) {
player.move(Direction.WEST);
} else if(Keyboard.isKeyPressed(Key.D)) {
player.move(Direction.EAST);
} else if(Keyboard.isKeyPressed(Key.ESCAPE)) {
window.close();
}
}
}
/**
* Update at a fixed rate (20Hz).
*/
public void handleLogic() {
player.update();
}
/**
* Updates as fast as possible. Draws all objects onto the screen.
*/
public void handleDrawing() {
/* The window has automatic double-buffering. */
window.clear();
/* Draw each object like layers, background to foreground. */
camera.centerOn(player.getAnimatedSprite());
window.draw(player.getMap());
window.draw(player);
camera.centerOnDefault();
window.draw(fpsUI);
window.display();
}
}