Files
GTSchoolShit/CS2335/FinalSubmission/src/edu/gatech/cs2335/lemmings/engine/GameEngine.java
2025-06-07 01:59:34 -04:00

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);
}
}
}