package edu.gatech.cs2335.lemmings.engine; import java.awt.Rectangle; import edu.gatech.cs2335.lemmings.gui.LFader; import edu.gatech.cs2335.lemmings.gui.LApplication; import edu.gatech.cs2335.lemmings.networking.AbstractMessage; import edu.gatech.cs2335.lemmings.networking.LemmingNetworking; import edu.gatech.cs2335.lemmings.file.LevelReader; /** * This class will manage the states of the game and their * transitions. It will know when to go to the splash screen or the * menu, or the game itself, and when to quit. * * @author Vladimir Urazov */ public class GameEngine { /** * Display debug information? */ public static final boolean VERBOSE = false; /** * Display a lot of debug information? */ public static final boolean DEBUG = false; /** * Singleton implementation. */ private static GameEngine instance; /** * This is the state that the game is currently in. */ private AbstractGameState currentState; /** * This is the application that will be started when the game starts. */ private LApplication theApp; /** * Cache this guy so we don't have to create him on the fly. */ private LoadLevelState loadLevelState; /** * The cached d00d. */ private EstablishingConnectionState ecs; /** * Like, another chached d00d, and stuff. */ private NetworkErrorState nes; /** * Creates a new GameEngine instance. * */ private GameEngine() { if (VERBOSE) { System.out.println("GameEngine: Initializing..."); System.out.flush(); } loadLevelState = new LoadLevelState(); ecs = new EstablishingConnectionState(); nes = new NetworkErrorState(); theApp = new LApplication("CS2335 Lemmings", null, null); theApp.startRenderer(); } /** * Singleton implementation. * * @return a GameEngine value */ public static synchronized GameEngine getInstance() { if (instance == null) { instance = new GameEngine(); } return instance; } /** * When a network error occurs, this function will be called. * * @param error a String value */ public synchronized void showNetworkError(String error) { //Show error: nes.setErrorMessage(error); setCurrentState(nes); if (VERBOSE) { System.err.println("GameEngine: Showing network error:"); System.err.println(error); System.err.flush(); } //Shut down networking: LemmingNetworking.getInstance().shutDownNetworking(); } /** * Starts a single-player game with the specified level. * * @param name a String value */ public void startSingleLevel(String name) { setCurrentState(loadLevelState); //Collect garbage now: System.gc(); //Now that we've cleaned shit up... loadLevelState.loadLevel(name); } /** * Accessor for EstablishingConnectionState * @return EstablishingConnectionState */ public EstablishingConnectionState getEcs() { return ecs; } /** * Describe startMultiGame method here. * */ public void startMultiGame() { setCurrentState(ecs); //Collect garbage now: System.gc(); ecs.loadLevel(LevelReader.getInstance().getLevelList()[0]); } /** * stuff. * * @param count an int value * @param lemmings an int value */ public void startMultiLevel(int count, int lemmings) { setCurrentState(ecs); //Collect garbage now: System.gc(); ecs.setLemmingCount(lemmings); ecs.loadLevel(LevelReader.getInstance().getLevelList()[count]); } /** * Access method for the currentState property. * * @return the current value of the currentState property */ public AbstractGameState getCurrentState() { return currentState; } /** * Sets the value of the currentState property. If the value passed * in is NULL, will throw a NullPointerException. * * @param aCurrentState the new value of the currentState property */ public void setCurrentState(final AbstractGameState aCurrentState) { boolean shitHitTheFan = false; boolean fade = false; if (currentState != null) { fade = true; } if (fade) { LFader f = new LFader(); f.setBounds(new Rectangle(0, 0, 800, 600)); f.setShown(true); theApp.getRootPane().addChild(f); f.fadeToForeground(1000); currentState.cleanUp(); currentState = aCurrentState; currentState.initialize(); if (f.isFading()) { try { Thread.sleep(f.getTimeRemaining()); } catch (Exception e) { //Too bad: //Don't mess with this! This exception is thrown when the //next screen loads faster than the fader fully fades to //black (because Java is screwed in the head and doesn't //support normal thread wake up. shitHitTheFan = true; // System.out.println("Exception in GameEngine\n"); } } } else { currentState = aCurrentState; currentState.initialize(); } //Set up the new root pane: theApp.setRootPane(currentState.getUI()); theApp.getRootPane().makeDirty(); } /** * Describe receiveMessage method here. * * @param msg an AbstractMessage value */ public synchronized void receiveMessage(AbstractMessage msg) { if (msg == null) { System.err.println("GameEngine: receiveMessage got bad message\n"); return; } //check if we're in the MultiplayerGameState if (currentState instanceof MultiplayerGameplayState) { ((MultiplayerGameplayState) currentState).receiveMessage(msg); } } }