243 lines
5.9 KiB
Java
243 lines
5.9 KiB
Java
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 <A HREF="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</A>
|
|
*/
|
|
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 <code>GameEngine</code> 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 <code>GameEngine</code> 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 <code>String</code> 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 <code>String</code> 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 <code>startMultiGame</code> method here.
|
|
*
|
|
*/
|
|
public void startMultiGame() {
|
|
setCurrentState(ecs);
|
|
|
|
//Collect garbage now:
|
|
System.gc();
|
|
|
|
ecs.loadLevel(LevelReader.getInstance().getLevelList()[0]);
|
|
}
|
|
|
|
/**
|
|
* stuff.
|
|
*
|
|
* @param count an <code>int</code> value
|
|
* @param lemmings an <code>int</code> 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 <code>receiveMessage</code> method here.
|
|
*
|
|
* @param msg an <code>AbstractMessage</code> 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);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|