package com.jakehorsfield.platformer.base;
import com.jakehorsfield.platformer.objects.tiles.TileGrid;
import com.jakehorsfield.platformer.objects.tiles.TileType;
import com.jakehorsfield.platformer.player.Player;
import com.jakehorsfield.platformer.states.State;
import org.lwjgl.LWJGLException;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.util.vector.Vector2f;
import java.io.File;
import java.util.logging.Level;
import java.util.logging.Logger;
import static org.lwjgl.opengl.GL11.*;
public class Main { // TODO: Tidy up this class.
private long lastLoopTime = System.nanoTime();
private final long OPTIMAL_TIME;
private long lastFpsTime;
private int fps;
private Player player;
private TileGrid grid;
private Menu menu;
private TileType selectedTile = TileType.NORMAL_TILE;
private boolean saveEnabled;
private float versionNumber = 0.2f;
public Main() {
saveEnabled = false;
OPTIMAL_TIME = 1000000000 / 60;
}
private void start() {
initDisplay();
initGL();
initObjects();
gameLoop();
cleanUp();
}
private void gameLoop() {
System.out.println("Game loop started");
while (!Display.isCloseRequested()) {
long now = System.nanoTime();
long updateLength = now - lastLoopTime;
lastLoopTime = now;
double delta = updateLength / ((double) OPTIMAL_TIME);
lastFpsTime += updateLength;
fps++;
getInput();
update(delta);
render();
if (((lastLoopTime - System.nanoTime() + OPTIMAL_TIME) / 1000000) > 0) {
try {
Thread.sleep((lastLoopTime - System.nanoTime() + OPTIMAL_TIME) / 1000000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
private void getInput() {
player.getInput();
if (State.getState() == State.MENU) {
menu.getInput();
}
}
private void update(double delta) {
grid.update(delta);
player.update(delta);
updateTitle();
/* Place a block */
if (Mouse.isButtonDown(0) && State.getState() == State.PLAY && grid.getAt(Mouse.getX() / 32, Mouse.getY() / 32) != selectedTile) {
int mouseX = Mouse.getX() / 32;
int mouseY = Mouse.getY() / 32;
grid.setAt(selectedTile, mouseX, mouseY);
}
/* Remove a block */
if (Mouse.isButtonDown(1) && State.getState() == State.PLAY) {
int mouseX = Mouse.getX() / 32;
int mouseY = Mouse.getY() / 32;
if (grid.getAt(mouseX, mouseY) != TileType.AIR) {
grid.setAt(TileType.AIR, mouseX, mouseY);
}
}
/* Save the map */
if (Keyboard.isKeyDown(Keyboard.KEY_S) && Debug.debugMode) {
grid.save(new File("res/maps/map.xml"));
System.out.println("Saved");
}
/* Enter the playing state, change this once finished! */
if (Keyboard.isKeyDown(Keyboard.KEY_RETURN) && State.getState() != State.PLAY) {
State.setState(State.PLAY);
}
if (Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)) {
System.exit(0);
}
if (Keyboard.isKeyDown(Keyboard.KEY_1) && Debug.debugMode) selectedTile = TileType.NORMAL_TILE;
if (Keyboard.isKeyDown(Keyboard.KEY_2) && Debug.debugMode) selectedTile = TileType.GRASS_TILE;
if (Keyboard.isKeyDown(Keyboard.KEY_3) && Debug.debugMode) selectedTile = TileType.DIRT_TILE;
if (Keyboard.isKeyDown(Keyboard.KEY_F11)) Debug.debugMode = true;
if (Keyboard.isKeyDown(Keyboard.KEY_F12)) Debug.debugMode = false;
}
private void updateTitle() {
if (lastFpsTime >= 1000000000) {
Display.setTitle("LWJGL Platformer v" + versionNumber + " | FPS: " + fps);
lastFpsTime = 0;
fps = 0;
}
}
private void render() {
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
switch (State.getState()) {
case MENU:
menu.render();
break;
case PLAY:
grid.render();
player.render();
if (Debug.debugMode) Debug.printDebug(player);
break;
}
Display.update();
Display.sync(60);
}
private void initObjects() {
System.out.println("Initialising objects");
grid = new TileGrid();
grid.load(new File("res/maps/map.xml"));
player = new Player(new Vector2f(32, 32), 32, 32);
menu = new Menu();
State.setState(State.MENU);
}
private void initDisplay() {
System.out.println("Initialising display");
try {
Display.setDisplayMode(new DisplayMode(1024, 640));
Display.setTitle("LWJGL Platformer v" + versionNumber);
Display.setVSyncEnabled(true);
Display.create();
Keyboard.create();
} catch (LWJGLException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
private void initGL() {
System.out.println("Initialising opengl");
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, Display.getWidth(), 0, Display.getHeight(), -1, 1);
glMatrixMode(GL_MODELVIEW);
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
private void cleanUp() {
System.out.println("Cleaning up");
Display.destroy();
Keyboard.destroy();
}
public static void main(String[] args) {
Main main = new Main();
main.start();
}
}