package engine;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import menu.IMenu;
import menu.MainMenu;
import menu.PauseMenu;
import view.SpaceCamera;
import com.threed.jpct.Config;
import com.threed.jpct.FrameBuffer;
import com.threed.jpct.IRenderer;
import com.threed.jpct.Loader;
import com.threed.jpct.Logger;
import com.threed.jpct.Object3D;
import com.threed.jpct.Texture;
import com.threed.jpct.TextureManager;
import com.threed.jpct.World;
import com.threed.jpct.procs.BloomGLProcessor;
import com.threed.jpct.util.SkyBox;
import font.GLFont;
public class Application {
private World world;
private World mainMenuWorld;
private World pauseMenuWorld;
private FrameBuffer buffer;
private SpaceCamera spaceCamera;
private Universe universe;
private SkyBox skyBox;
private BloomGLProcessor bloom;
private MainMenu mainMenu;
private PauseMenu pauseMenu;
private FPSCounter fpsCounter;
private boolean showFPS;
private static GLFont font;
private static GLFont bigFont;
Timer logicTimer;
private final int LOGIC_FPS = 60;
private boolean f1ButtonDown, escButtonDown;
private boolean pauseOn = false;
private enum GameState {
MAIN_MENU, START_GAME, PLAY_GAME, PAUSE_GAME, STOP_GAME, END_GAME
}
private GameState actualGameState;
private String defeatMessage;
private String victoryMessage;
private Dimension defeatDim;
private Dimension victoryDim;
public Application() {
Resources.loadResources();
font = new GLFont(new Font("Arial", Font.BOLD, 30));
bigFont = new GLFont(new Font("Arial", Font.BOLD, 60));
actualGameState = GameState.MAIN_MENU;
TextureManager.getInstance().addTexture("orange", new Texture(32, 32, Color.ORANGE));
TextureManager.getInstance().addTexture("black", new Texture(32, 32, Color.BLACK));
TextureManager.getInstance().addTexture("red", new Texture(8, 8, Color.RED));
}
private void startGame() {
buffer.clear(java.awt.Color.BLACK);
font.blitString(buffer, "LOADING...", 600, 70, 100, Color.white);
buffer.update();
buffer.displayGLOnly();
onInit();
onLoad();
actualGameState = GameState.PLAY_GAME;
}
private void playGame() {
if (Keyboard.KEY_ESC && universe.getVictory() != 0) {
actualGameState = GameState.MAIN_MENU;
Keyboard.KEY_ESC = false;
} else if (Keyboard.KEY_ESC && !escButtonDown) {
escButtonDown = true;
pauseOn = !pauseOn;
} else if (!Keyboard.KEY_ESC) {
escButtonDown = false;
}
if (pauseOn) {
actualGameState = GameState.PAUSE_GAME;
logicTimer.stop();
universe.stopPointIncrementation();
} else {
long ticks = logicTimer.getElapsedTicks();
for (int i = 0; i < ticks; i++) {
onLogicLoop();
}
onLoop();
fpsCounter.addFrame();
}
}
private void pauseGame() {
int result = pauseMenu.getResult();
if (result == 1) {
actualGameState = GameState.PLAY_GAME;
pauseOn = false;
logicTimer.start();
universe.startPointIncrementation();
} else if (result == 2) {
actualGameState = GameState.START_GAME;
pauseOn = false;
} else if (result == 3) {
actualGameState = GameState.MAIN_MENU;
pauseOn = false;
}
onPauseMenuLoop();
}
private void stopGame() {
}
private boolean useMenu() {
int result = mainMenu.getResult();
if (result == 1) {
actualGameState = GameState.START_GAME;
} else if (result == 2) {
mainMenu.dispose();
return false;
}
onMainMenuLoop();
return true;
}
/**
* Implements game lifecycle.
*/
public void start() {
onWindowInit();
onMainMenuInit();
onPauseMenuInit();
while (!org.lwjgl.opengl.Display.isCloseRequested()) {
if (actualGameState == GameState.START_GAME) {
startGame();
} else if (actualGameState == GameState.PLAY_GAME) {
playGame();
} else if (actualGameState == GameState.PAUSE_GAME) {
pauseGame();
} else if (actualGameState == GameState.STOP_GAME) {
stopGame();
} else if (actualGameState == GameState.MAIN_MENU) {
if (!useMenu()) {
break;
}
}
}
onExit();
}
private void onWindowInit() {
Config.maxPolysVisible = 100000;
TextureManager.getInstance().addTexture("yellow", new Texture(32, 32, Color.YELLOW));
buffer = new FrameBuffer(800, 600, FrameBuffer.SAMPLINGMODE_GL_AA_4X);
buffer.disableRenderer(IRenderer.RENDERER_SOFTWARE);
buffer.enableRenderer(IRenderer.RENDERER_OPENGL);
defeatMessage = "DEFEAT";
defeatDim = font.getStringBounds(defeatMessage);
victoryMessage = "VICTORY";
victoryDim = font.getStringBounds(victoryMessage);
}
private void onMainMenuInit() {
mainMenuWorld = new World();
mainMenuWorld.setAmbientLight(255, 255, 255);
mainMenu = new MainMenu();
mainMenu.initialize(mainMenuWorld, buffer);
}
private void onPauseMenuInit() {
pauseMenuWorld = new World();
pauseMenuWorld.setAmbientLight(255, 255, 255);
pauseMenu = new PauseMenu();
pauseMenu.initialize(pauseMenuWorld, buffer);
}
private void onMenuLoop(IMenu menu, World menuWorld) {
buffer.clear(java.awt.Color.BLACK);
menu.update(menuWorld, buffer);
menuWorld.renderScene(buffer);
menuWorld.draw(buffer);
buffer.update();
buffer.displayGLOnly();
}
private void onPauseMenuLoop() {
onMenuLoop(pauseMenu, pauseMenuWorld);
}
private void onMainMenuLoop() {
onMenuLoop(mainMenu, mainMenuWorld);
}
/**
* Initializes buffer and world basic preferences.
*/
private void onInit() {
world = new World();
world.setAmbientLight(255, 255, 255);
spaceCamera = new SpaceCamera(world.getCamera());
fpsCounter = new FPSCounter();
showFPS = false;
logicTimer = new Timer(1000 / LOGIC_FPS);
logicTimer.start();
bloom = new BloomGLProcessor();
bloom.init(buffer);
f1ButtonDown = false;
}
/**
* Loads all needed content e.g. textures, models and creates world.
*/
private void onLoad() {
universe = UniverseFactory.createRandom(15);
if (universe == null) {
System.exit(1);
}
universe.onInit(world, buffer);
createSun();
skyBox = new SkyBox(400.0f);
skyBox.compile();
}
/**
* That method is executed 60 times per second with warranty. Speed can be
* modified by changing LOGIC_FPS field;
*/
private void onLogicLoop() {
universe.onLogicUpdate(world, buffer);
}
/**
* That method is executed every single frame.
*/
private void onLoop() {
Keyboard.handleKeys();
if (Keyboard.KEY_F1 && !f1ButtonDown) {
f1ButtonDown = true;
showFPS = !showFPS;
} else if (!Keyboard.KEY_F1) {
f1ButtonDown = false;
}
spaceCamera.update();
buffer.clear(java.awt.Color.BLACK);
skyBox.render(world, buffer);
world.renderScene(buffer);
world.draw(buffer);
// draw always just before buffer update.
bloom.process();
universe.onUpdate(world, buffer);
if (universe.getVictory() == -1) {
bigFont.blitString(buffer, defeatMessage, 270, 30 + defeatDim.height, 100, Color.white);
} else if (universe.getVictory() == 1) {
bigFont.blitString(buffer, victoryMessage, 270, 30 + victoryDim.height, 100, Color.white);
}
if (showFPS)
fpsCounter.draw(buffer, 10, 30);
buffer.update();
buffer.displayGLOnly();
}
/**
* Frees resources, disables renderer.
*/
private void onExit() {
if (skyBox != null) {
skyBox.dispose();
}
buffer.disableRenderer(IRenderer.RENDERER_OPENGL);
buffer.dispose();
System.exit(0);
}
public void createSun() {
Object3D sun = Loader.loadOBJ("content/planet.obj", null, 1.0f)[0];
if (sun == null) {
Logger.log("Could not load sun object.");
}
sun.setScale(10.0f);
sun.setTexture("SUN");
sun.compile();
sun.build();
world.addObject(sun);
}
}