first commit

This commit is contained in:
Jose Caban
2025-06-07 01:59:34 -04:00
commit 388ac241f0
3558 changed files with 9116289 additions and 0 deletions

View File

@@ -0,0 +1,68 @@
package edu.gatech.cs2335.lemmings.engine;
import java.awt.event.ActionListener;
import edu.gatech.cs2335.lemmings.gui.LRootPane;
/**
* This is the parent of all the game state classes. A game state is
* basically one screen - be it the splash screen, the main menu, or
* the game screen itself.
*
* @author <A HREF="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</A>
*/
public abstract class AbstractGameState implements ActionListener {
/**
* The UI to display with this state.
*/
private LRootPane gui;
/**
* Creates a new <code>AbstractGameState</code> instance.
*
*/
protected AbstractGameState() {
gui = new LRootPane();
}
/**
* Returns the root pane with the UI associated with this state.
*
* @return a <code>LRootPane</code> value
*/
public final LRootPane getUI() {
return gui;
}
/**
* Sets a new value of the root pane.
*
* @param pane a <code>LRootPane</code> value
*/
protected final void setUI(LRootPane pane) {
gui = pane;
}
//@roseuid 40651ACF00AB
/**
* This method will initialize the state that it belongs to. It will
* then return true upon success, and false upon failure.
*
* @return True if the initialization was successful, and false if
* it was not.
*
*/
public abstract boolean initialize();
//@roseuid 40651B230193
/**
* This method will perform all of the necessary clean up operations
* once the object is no longer needed.
*
* @return True if the clean-up was successful, and false if it failed.
*
*/
public abstract boolean cleanUp();
}

View File

@@ -0,0 +1,164 @@
package edu.gatech.cs2335.lemmings.engine;
import java.awt.event.ActionEvent;
import edu.gatech.cs2335.lemmings.engine.lemmingjob.LemmingJobSettings;
import edu.gatech.cs2335.lemmings.engine.lemmingjob.LemmingJobFactory;
import edu.gatech.cs2335.lemmings.gui.LComponent;
import edu.gatech.cs2335.lemmings.gui.LLeafComponent;
import edu.gatech.cs2335.lemmings.gui.IClickable;
import java.awt.Graphics;
import java.awt.Dimension;
//import java.awt.image.BufferedImage;
import java.util.List;
import java.awt.Point;
/**
* Class GamePlayState: where the actual game is displayed and played
*
*
*/
public class AttractState extends GamePlayState {
/**
* Allow more bashers?
*/
private boolean basher = true;
/**
* Allow more bashers?
*/
private boolean bridger = true;
/**
* Constructor
* @param l , Level
*/
public AttractState(Level l) {
super(l);
}
/**
* Constructor
* @param l , string of level name
*/
public AttractState(String l) {
super(l);
}
/**
* Handles the special update.
*/
protected void specialUpdate() {
Lemming currLem = null;
// BufferedImage map = getLevel().getMap().getMap();
List lemmings = getLevel().getActiveLemmings();
int x;
int y;
if (getLevel().getLemmingHeaven().size() == 20) {
GameEngine.getInstance().setCurrentState(new MainMenuState());
}
for (int i = 0; i < lemmings.size(); i++) {
currLem = (Lemming) lemmings.get(i);
x = currLem.getPosition().getX() + 5;
y = currLem.getPosition().getY() + 5;
// System.out.println("In special update x is " + x + "y is " + y);
//check for digger
if (x >= 156 && y < 122) {
currLem.setOccupation(
LemmingJobFactory.getInstance().makeJob(
LemmingJobSettings.JOB_ID_DIGGER));
}
//check for exploder
if (x >= 615 && x <= 620 && y >= 225 && y <= 230) {
currLem.setOccupation(
LemmingJobFactory.getInstance().makeJob(
LemmingJobSettings.JOB_ID_EXPLODER));
}
//check for basher
if (x >= 220 && x <= 250 && y >= 282 && y <= 288 && basher) {
basher = false;
currLem.setOccupation(
LemmingJobFactory.getInstance().makeJob(
LemmingJobSettings.JOB_ID_BASHER));
}
//check for climber
if (x >= 210 && x <= 220 && y >= 590 && y <= 595) {
currLem.setOccupation(
LemmingJobFactory.getInstance().makeJob(
LemmingJobSettings.JOB_ID_CLIMBER));
}
//check for floater
if (x >= 130 && x <= 180 && y >= 220 && y <= 235) {
currLem.setOccupation(
LemmingJobFactory.getInstance().makeJob(
LemmingJobSettings.JOB_ID_FLOATER));
}
//check for bridger
if (x >= 340 && x <= 345 && y >= 282 && y <= 288 && bridger) {
bridger = false;
currLem.setOccupation(
LemmingJobFactory.getInstance().makeJob(
LemmingJobSettings.JOB_ID_BRIDGER));
}
}
}
/**
* This function essentially processes the action event that may
* have been thrown by the UI.
*
* @param ae ae
*/
public void actionPerformed(ActionEvent ae) {
GameEngine.getInstance().setCurrentState(new MainMenuState());
}
/**
* Whatever else needs to be initialized.
*/
protected void specialInitialize() {
LComponent c = new LClickListener() {
public void registerMouseClick(int button, Point coords) {
GameEngine.getInstance().setCurrentState(new MainMenuState());
}
};
c.setPosition(new Point(0, 0));
c.setSize(new Dimension(800, 600));
c.setShown(true);
getUI().addChild(c);
}
/**
* Listens to keys and stuff.
*/
private abstract class LClickListener
extends LLeafComponent implements IClickable {
/**
* Deep-copies self <b>into the component</b> passed in.
*
* @param component a <code>LComponent</code> value
*/
protected void copy(LComponent component) {
}
/**
* Performs all of the necessary drawing for this control only. The
* children will be taken care of separately. This method need not
* concern itself with them.
*
* @param g a <code>Graphics</code> value
* @return a <code>boolean</code> value
*/
protected boolean paint(Graphics g) {
return true;
}
}
}

View File

@@ -0,0 +1,105 @@
package edu.gatech.cs2335.lemmings.engine;
import java.util.Random;
/**
* Class Particle: When a lemming blows up, he makes particles. Well,
* here they are. :)
*
* Description from Jose:
* Adds specific blood stuff
*
* Blood shouldn't bounce, rather it should hit the wall and die
*
* <PRE>
* Revision History:
* v1.0 (Apr. 11, 2004) - Created the BloodParticle class
* </PRE>
*
* @author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose Caban</A>
* @version Version 1.0, Apr. 11, 2004
*/
public class BloodParticle extends Particle {
/**
* Used to randomize velocity.
*/
private static final Random GENERATOR = new Random(new java.util.Date()
.getTime());
/**
* Particles to create when death should occur
*/
public static final int PARTICLESWHENDIE = 75;
/**
* time to Live
*/
private int killMe;
/**
* curve
*/
private int curve;
/**
* Stores canDie
*/
private boolean canDie;
/**
* Creates a new <code>Particle</code> instance.
*/
public BloodParticle() {
super("blood");
getVelocity().setPolar(GENERATOR.nextInt(8), GENERATOR.nextInt(30));
canDie = false;
killMe = 0;
curve = 0;
}
/**
* Should return canDie
*
* @return <code>boolean</code> value
*/
public boolean getCanDie() {
return canDie;
}
/**
* Should return canDie
*
* @param a for candie <code>boolean</code> value
*/
public void setCanDie(boolean a) {
canDie = a;
}
/**
* Should return true when the sprite is ready to kill self.
*
* @return a <code>boolean</code> value
*/
protected boolean canKillSelf() {
if (killMe > 25) {
return true;
}
if (curve > 5) {
return true;
} else if (this.getVelocity().getJ() == 0) {
curve++;
}
killMe++;
return canDie;
}
}

View File

@@ -0,0 +1,63 @@
package edu.gatech.cs2335.lemmings.engine;
import java.util.Random;
/**
* Class Particle: When a lemming blows up, he makes particles. Well,
* here they are. :)
*
* Description from Andrew:
* Adds specific bone stuff
*
* bones reaches peak in curve three before disapearing
*
* <PRE>
* Revision History:
* v1.0 (Apr. 11, 2004) - Created the BoneParticle class
* </PRE>
*
* @author <A HREF="mailto:gtg284h@mail.gatech.edu">Andrew Knight</A>
* @version Version 1.0, Apr. 11, 2004
*/
public class BoneParticle extends Particle {
/**
* Used to randomize velocity.
*/
private static final Random GENERATOR = new Random(new java.util.Date()
.getTime());
/**
* Particles to create when death should occur
*/
public static final int PARTICLESWHENBONE = 3;
/**
* curve
*/
private int curve;
/**
* Creates a new <code>Particle</code> instance.
*/
public BoneParticle() {
super("bone");
getVelocity().setPolar(GENERATOR.nextInt(8), GENERATOR.nextInt(30));
curve = 0;
}
/**
* Should return true when the sprite is ready to kill self.
*
* @return a <code>boolean</code> value
*/
protected boolean canKillSelf() {
if (curve > 3) {
return true;
} else if (this.getVelocity().getJ() == 0) {
curve++;
}
return false;
}
}

View File

@@ -0,0 +1,94 @@
package edu.gatech.cs2335.lemmings.engine;
import java.awt.Point;
import java.awt.event.ActionEvent;
import edu.gatech.cs2335.lemmings.gui.LButton;
import edu.gatech.cs2335.lemmings.gui.LRootPane;
import edu.gatech.cs2335.lemmings.graphics.Looping;
import edu.gatech.cs2335.lemmings.graphics.Direction;
import edu.gatech.cs2335.lemmings.graphics.AnimatedSprite;
import edu.gatech.cs2335.lemmings.graphics.TileSetManager;
/**
* Class CreditsState: Displays the credits screen, and when we are
* done - goes back to the main menu.
*
* <PRE>
* Revision History:
* v1.0 (Apr. 15, 2004) - Created the CreditsState class
* </PRE>
*
* @author <A HREF="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</A>
* @version Version 1.0, Apr. 15, 2004
*/
public class CreditsState extends AbstractGameState {
/**
* Creates a new <code>CreditsState</code> instance.
*/
public CreditsState() {
}
//@roseuid 4065D29C032F
/**
* This method will initialize the state that it belongs to. It will
* then return true upon success, and false upon failure.
*
* @return boolean
*
*/
public boolean initialize() {
LRootPane np = new LRootPane();
LButton button = new LButton();
button.setImage(new AnimatedSprite(TileSetManager.getInstance()
.getTileSet("credits"),
Direction.NO_DIRECTION, Looping.NONE));
button.addActionListener(this);
button.setShown(true);
button.setPosition(new Point(0, 0));
np.addChild(button);
setUI(np);
return true;
}
//@roseuid 4065D29C034D
/**
* This method will perform all of the necessary clean up operations
* once the object is no longer needed.
*
* @return boolean
*
*/
public boolean cleanUp() {
return true;
}
//@roseuid 4065D29C037F
/**
* This function essentially processes the action event that may
* have been thrown by the UI.
*
* @param ae ada
*
*/
public void actionPerformed(ActionEvent ae) {
//The splash screen has been clicked.
if (GameEngine.VERBOSE) {
System.out.println("CreditsState: Transferrring to Main Menu...");
System.out.flush();
}
//Transfer to Main Menu.
MainMenuState mms = new MainMenuState();
GameEngine.getInstance().setCurrentState(mms);
}
}

View File

@@ -0,0 +1,79 @@
package edu.gatech.cs2335.lemmings.engine;
import java.util.Random;
/**
* Class Particle: When a lemming blows up, he makes particles. Well,
* here they are. :)
*
* Description from Andrew:
* Adds specific dirt stuff
*
* Dirt reaches peak in curve twice before it disapears
*
* <PRE>
* Revision History:
* v1.0 (Apr. 11, 2004) - Created the DirtParticle class
* </PRE>
*
* @author <A HREF="mailto:gtg284h@mail.gatech.edu">Andrew Knight</A>
* @version Version 1.0, Apr. 11, 2004
*/
public class DirtParticle extends Particle {
/**
* Used to randomize velocity.
*/
private static final Random GENERATOR = new Random(new java.util.Date()
.getTime());
/**
* Particles to create when death should occur
*/
public static final int PARTICLESWHENDIG = 4;
/**
* curve
*/
private int curve;
/**
* Creates a new <code>Particle</code> instance.
*/
public DirtParticle() {
super("dirt");
getVelocity().setPolar(GENERATOR.nextInt(8), GENERATOR.nextInt(30));
curve = 0;
}
/**
* Creates a new <code>Particle</code> instance.
*@param i i
*@param j j
*/
public DirtParticle(int i, int j) {
super("dirt");
getVelocity().setI(-i + GENERATOR.nextInt(3));
getVelocity().setJ(-j + GENERATOR.nextInt(3));
curve = 0;
}
/**
* Should return true when the sprite is ready to kill self.
*
* @return a <code>boolean</code> value
*/
protected boolean canKillSelf() {
if (curve > 2) {
return true;
} else if (this.getVelocity().getJ() == 0) {
curve++;
}
return false;
}
}

View File

@@ -0,0 +1,247 @@
package edu.gatech.cs2335.lemmings.engine;
import java.awt.Font;
import java.awt.Color;
import java.awt.Point;
import java.awt.event.ActionEvent;
import edu.gatech.cs2335.lemmings.file.LevelReader;
import edu.gatech.cs2335.lemmings.gui.LIcon;
//import edu.gatech.cs2335.lemmings.gui.LButton;
import edu.gatech.cs2335.lemmings.gui.LFancyLabel;
import edu.gatech.cs2335.lemmings.gui.LRootPane;
import edu.gatech.cs2335.lemmings.graphics.TileSetManager;
import edu.gatech.cs2335.lemmings.networking.LemmingNetworking;
/**
* Class EstablishingConnectionState: This state will load a level,
* and then wait for a connection to be established. After both of the
* conditions are met, it will go on to the actual game.
*
* <PRE>
* Revision History:
* v1.0 (Apr. 15, 2004) - Created the EstablishingConnectionState class
* </PRE>
*
* @author <A HREF="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</A>
* @version Version 1.0, Apr. 15, 2004
*/
public class EstablishingConnectionState extends AbstractGameState {
/**
* The level that we will be loading here.
*/
private Level level;
/**
* Allows the user to continue on to play the level.
*/
// private LButton continueButton;
/**
* The label to display our message to the user in.
*/
private LFancyLabel message;
/**
* Describe variable <code>levelLoaded</code> here.
*
*/
private boolean islevelLoaded;
/**
* Contains true if the connection is established, and false if it
* is not yet.
*/
private boolean connectionEstablished;
/**
* Port.
*/
private int port;
/**
* Host.
*/
private String host;
/**
* Describe variable <code>lemmingCount</code> here.
*
*/
private int lemmingCount;
/**
* Creates a new <code>EstablishingConnectionState</code> instance.
*/
public EstablishingConnectionState() {
connectionEstablished = false;
islevelLoaded = false;
level = null;
lemmingCount = 0;
//Initialize background:
LIcon bg = new LIcon(TileSetManager.getInstance()
.getTileSet("bg_loading"));
bg.setShown(true);
bg.setPosition(new Point(0, 0));
//Initialize label:
message = new LFancyLabel();
message.setForeground(Color.black);
message.setFont(LFancyLabel.DEFAULT_FONT.deriveFont(Font.BOLD, 18.0f));
message.setText("Establishing Connection...");
message.setShown(true);
message.setPosition(new Point(300, 300));
//Initialize UI:
LRootPane np = new LRootPane();
np.addChild(bg);
np.addChild(message);
setUI(np);
}
/**
* This method will initialize the state that it belongs to. It will
* then return true upon success, and false upon failure.
*
* @return boolean
*/
public boolean initialize() {
return true;
}
/**
* This method will perform all of the necessary clean up operations
* once the object is no longer needed.
*
* @return boolean
*
*/
public boolean cleanUp() {
level = null;
connectionEstablished = false;
islevelLoaded = false;
port = 0;
host = null;
lemmingCount = 0;
return true;
}
/**
* This function essentially processes the action event that may
* have been thrown by the UI.
*
* @param ae ae
*
*/
public void actionPerformed(ActionEvent ae) {
//The user can't click anything here, so...
}
/**
* Get the value of lemmingCount.
* @return value of lemmingCount.
*/
public int getLemmingCount() {
return lemmingCount;
}
/**
* Set the value of lemmingCount.
* @param v Value to assign to lemmingCount.
*/
public void setLemmingCount(int v) {
this.lemmingCount = v;
}
/**
* Describe <code>connectTo</code> method here.
*
* @param hostt a <code>String</code> value
* @param portt an <code>int</code> value
*/
public void connectTo(String hostt, int portt) {
host = hostt;
port = portt;
//We are the client:
if (LemmingNetworking.getInstance().connectTo(host, port)) {
connectionEstablished();
}
}
/**
* Describe <code>host</code> method here.
*
* @param portt an <code>int</code> value
*/
public void host(int portt) {
port = portt;
//We are the server:
if (LemmingNetworking.getInstance().listenForConnection(port)) {
connectionEstablished();
}
}
/**
* Loads the level with the specified id.
*
* @param id a <code>String</code> value
*/
public synchronized void loadLevel(final String id) {
level = LevelReader.getInstance().loadLevel(id);
levelLoaded();
}
/**
* This function will be done when the level is done loading.
*/
private synchronized void levelLoaded() {
islevelLoaded = true;
//Set the number of lemmings on the level to fourty plus whatever
//we have
int num = 40 + lemmingCount;
level.setNumberOfLemmings(num);
if (LemmingNetworking.getInstance().isConnected()) {
startLevel();
}
}
/**
* Will be called when the connection is established.
*/
private synchronized void connectionEstablished() {
if (islevelLoaded) {
startLevel();
}
}
/**
* Starts the level.
*/
private synchronized void startLevel() {
GameEngine.getInstance()
.setCurrentState(new MultiplayerGameplayState(level));
LemmingNetworking.getInstance().getConnection().startListening();
LemmingNetworking.getInstance().getConnection().startSending();
}
}

View File

@@ -0,0 +1,88 @@
package edu.gatech.cs2335.lemmings.engine;
import java.util.Random;
/**
* Class Particle: When a lemming blows up, he makes particles. Well,
* here they are. :)
*
* Description from Andrew:
* Adds specific flame stuff
*
* flames shoot downward and live for five process calls
*
* <PRE>
* Revision History:
* v1.0 (Apr. 11, 2004) - Created the FlameParticle class
* </PRE>
*
* @author <A HREF="mailto:gtg284h@mail.gatech.edu">Andrew Knight</A>
* @version Version 1.0, Apr. 11, 2004
*/
public class FlameParticle extends Particle {
/**
* Particles to create when death should occur
*/
public static final int PARTICLESWHENFLAME = 3;
/**
* Used to randomize velocity.
*/
private static final Random GENERATOR = new Random(new java.util.Date()
.getTime());
/**
* time to Live
*/
private int killMe;
/**
* Stores canDie
*/
private boolean canDie;
/**
* Creates a new <code>Particle</code> instance.
*/
public FlameParticle() {
super("flame");
killMe = 0;
getVelocity().setJ(2 + GENERATOR.nextInt(2));
getVelocity().setI((-1 * GENERATOR.nextInt(1)) * GENERATOR.nextInt(2));
}
/**
* Should return canDie
*
* @return <code>boolean</code> value
*/
public boolean getCanDie() {
return canDie;
}
/**
* Should return canDie
*
* @param a for candie <code>boolean</code> value
*/
public void setCanDie(boolean a) {
canDie = a;
}
/**
* Should return true when the sprite is ready to kill self.
*
* @return a <code>boolean</code> value
*/
protected boolean canKillSelf() {
if (killMe > 5 + GENERATOR.nextInt(3)) {
return true;
}
killMe++;
return canDie;
}
}

View File

@@ -0,0 +1,39 @@
package edu.gatech.cs2335.lemmings.engine;
import edu.gatech.cs2335.lemmings.physics.PhysicsSettings;
/**
* Class FlingTrap: when the lemming comes close to this one, it flings him.
*
* <PRE>
* Revision History:
* v1.0 (Apr. 22, 2004) - Created the FlingTrap class
* </PRE>
*
* @author <A HREF="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</A>
* @version Version 1.0, Apr. 22, 2004
*/
public class FlingTrap extends Portal {
/**
* Creates a new <code>FlingTrap</code> instance.
*/
public FlingTrap() {
super(PortalFactory.PORTAL_TYPES[2]);
}
/**
* This function will be called when a lemming enters this portal.
*
* @param l a <code>Lemming</code> value
*/
public void processLemmingEntry(Lemming l) {
int x = l.getVelocity().getI();
x /= Math.abs(x); //normalize
l.getVelocity().setI(x * PhysicsSettings.getInstance()
.getTerminalVelocity() / 2);
l.getVelocity().setJ(-PhysicsSettings.getInstance().getTerminalVelocity());
}
}

View File

@@ -0,0 +1,242 @@
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);
}
}
}

View File

@@ -0,0 +1,755 @@
package edu.gatech.cs2335.lemmings.engine;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.Point;
import java.awt.Color;
import java.awt.Rectangle;
import java.awt.Graphics;
import java.awt.Dimension;
//import java.util.List;
//import java.util.Vector;
import edu.gatech.cs2335.lemmings.engine.lemmingjob.LemmingJobSettings;
//import edu.gatech.cs2335.lemmings.networking.LemmingNetworking;
//import edu.gatech.cs2335.lemmings.networking.MessageFactory;
//import edu.gatech.cs2335.lemmings.networking.MessageSettings;
//import edu.gatech.cs2335.lemmings.networking.AbstractMessage;
import edu.gatech.cs2335.lemmings.graphics.Looping;
import edu.gatech.cs2335.lemmings.graphics.Direction;
import edu.gatech.cs2335.lemmings.graphics.AnimatedSprite;
import edu.gatech.cs2335.lemmings.graphics.TileSetManager;
import edu.gatech.cs2335.lemmings.gui.ITypable;
import edu.gatech.cs2335.lemmings.gui.LLeafComponent;
import edu.gatech.cs2335.lemmings.gui.LComponent;
import edu.gatech.cs2335.lemmings.gui.JobContainer;
import edu.gatech.cs2335.lemmings.gui.LRootPane;
import edu.gatech.cs2335.lemmings.gui.LButton;
import edu.gatech.cs2335.lemmings.gui.LToggleButton;
import edu.gatech.cs2335.lemmings.gui.LFancyLabel;
import edu.gatech.cs2335.lemmings.gui.GamePlayPanel;
import edu.gatech.cs2335.lemmings.graphics.Renderer;
import edu.gatech.cs2335.lemmings.physics.PhysicsEngine;
import edu.gatech.cs2335.lemmings.file.LevelReader;
import edu.gatech.cs2335.lemmings.gui.MiniMap;
/**
* The game state, where the actual game is displayed and played.
*
* @author <A HREF="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</A>
* @version 1.0
*/
public class GamePlayState extends AbstractGameState {
/**
* How many times per second should we update the lemmings?
*/
public static final float UPDATE_FREQUENCY = 10;
/**
* Delay between the updates.
*/
public static final long UPDATE_DELAY = (long) (1000.0f / UPDATE_FREQUENCY);
/**
* The level associated with this game. It will be what the player plays on.
*/
private Level level;
/**
* True if the game is paused. False if it is not.
*/
//private boolean paused;
/**
* Set to true when the state is killed.
*/
private boolean killed;
/**
* The delay between the updates.
*/
private long gameSpeed;
/**
* The label that shows the time...
*/
private LFancyLabel timeLabel;
/**
* The label showing the number of lemmings released.
*/
private LFancyLabel releasedLabel;
/**
* The label that will show how many lemmings have been saved.
*/
private LFancyLabel savedLabel;
/**
* This label will show the number of lemmings out in the field.
*/
private LFancyLabel outLabel;
/**
* Describe variable <code>jb</code> here.
*
*/
private JobContainer jobs;
/**
* Describe variable <code>pauseToggle</code> here.
*
*/
private LToggleButton pauseToggle;
/**
* Describe variable <code>speedToggle</code> here.
*
*/
private LToggleButton speedToggle;
/**
* Describe variable <code>nukeToggle</code> here.
*
*/
private LToggleButton nukeToggle;
/**
* Describe variable <code>gpp</code> here.
*
*/
private GamePlayPanel gpp;
/**
* The renderer used for this.
*/
private Renderer renderer;
/**
* Will display the current lemming flow.
*/
private LFancyLabel lblLemmingFlow;
/**
* time of last update
*/
private long lastUpdate;
/**
* Number of Lemmings
*/
private int numLemmings;
/**
* String representation of the number of lemmings
*/
private String strNumLemmings;
/**
* How many lemmings have to be saved
*/
private int lemmingsToSave;
/**
* String representation of the number of lemmings to save
*/
private String strLemmingsToSave;
/**
* Number of released lemmings
*/
private int numReleasedLemmings;
/**
* Number of lemmings out
*/
private int numLemmingsOut;
//@roseuid 406623D9022A
/**
* Creates a new GamePlayState instance.
*
* @param l The level that we would like to play on.
*
*/
public GamePlayState(Level l) {
level = l;
//paused = true;
killed = false;
gameSpeed = UPDATE_DELAY;
}
/**
* Loads the level with the id passed in and uses that to play.
*
* @param levelName a <code>String</code> value
*/
public GamePlayState(String levelName) {
this(LevelReader.getInstance().loadLevel(levelName));
}
/**
* Access method for the level property.
*
* @return the current value of the level property
*/
public Level getLevel() {
return level;
}
/**
* This method will initialize the state that it belongs to. It will
* then return true upon success, and false upon failure.
*
* @return boolean
*/
public boolean initialize() {
//Set up the game panel:
LRootPane np = new LRootPane();
Rectangle bounds = new Rectangle(0, 20, 800, 580);
renderer = new Renderer(level, new Rectangle(bounds));
gpp = new GamePlayPanel(renderer);
jobs = new JobContainer(level);
jobs.setShown(true);
jobs.setPosition(new Point(30, 570));
jobs.setArrangement(JobContainer.X_AXIS);
for (int i = 0; i < LemmingJobSettings.ALL_JOB_NAMES.length; i++) {
if (level.getJobsRemaining(LemmingJobSettings.ALL_JOB_NAMES[i]) > 0) {
jobs.addJobButton(LemmingJobSettings.ALL_JOB_NAMES[i]);
}
}
gpp.setBounds(new Rectangle(bounds));
gpp.setShown(true);
initializeLabels();
//Buttons:
initializeButtons();
LButton ib = new LButton();
ib.setImage(new AnimatedSprite(TileSetManager.getInstance()
.getTileSet("btn_increase"),
Direction.NO_DIRECTION,
Looping.NONE));
ib.addActionListener(this);
ib.setActionCommand("increase");
ib.setShown(true);
ib.setPosition(new Point(10, 290));
LButton db = new LButton();
db.setImage(new AnimatedSprite(TileSetManager.getInstance()
.getTileSet("btn_decrease"),
Direction.NO_DIRECTION,
Looping.NONE));
db.addActionListener(this);
db.setActionCommand("decrease");
db.setShown(true);
db.setPosition(new Point(10, 370));
np.addChild(gpp);
np.addChild(timeLabel);
np.addChild(releasedLabel);
np.addChild(savedLabel);
np.addChild(outLabel);
np.addChild(lblLemmingFlow);
np.addChild(jobs);
np.addChild(pauseToggle);
np.addChild(speedToggle);
np.addChild(nukeToggle);
np.addChild(ib);
np.addChild(db);
MiniMap mm = new MiniMap(level);
mm.setShown(true);
mm.setPosition(new Point(650, 450));
mm.setSize(new Dimension(120, 120));
np.addChild(mm);
setUI(np);
//Update physics engine
PhysicsEngine.getInstance().setCurrentMap(level.getMap().getMap());
specialInitialize();
np.addChild(new LKeyListener() {
public void processKeyTyped(char key, int modifiers) {
if (key == 'p') {
//Pause the game.
if (level.isPaused()) {
pauseToggle.setSelected(false);
handlePauseButton();
} else {
pauseToggle.setSelected(true);
handlePauseButton();
}
} else if (key == 'f') {
//Fast forward.
speedToggle.toggleSelected();
handleSpeedupButton();
} else if (key == '+') {
//Increase lemming flow:
handleIncreaseButton();
} else if (key == '-') {
//Decrease lemming flow:
handleDecreaseButton();
} else if (key == 27) { //ESC
try {
level.pause();
level.setLemmingsSaved(0);
endLevel();
} catch (NullPointerException npe) {
System.err.println("NullPointerException"); //tooo bad
}
}
}
});
//Set up update thread:
new Thread(new Runnable() {
public void run() {
lastUpdate = System.currentTimeMillis();
numLemmings = level.getPendingLemmings().size();
strNumLemmings = Integer.toString(numLemmings);
lemmingsToSave = level.getData().getPercentToSave();
lemmingsToSave = (numLemmings * lemmingsToSave) / 100;
strLemmingsToSave = Integer.toString(lemmingsToSave);
level.unpause();
while (!killed) {
//Update level:
level.updateLevel();
if (level.isLevelOver()) {
killed = true;
endLevel();
return;
}
numReleasedLemmings
= numLemmings - level.getPendingLemmings().size();
numLemmingsOut = level.getActiveLemmings().size();
//Update UI:
updateStuff();
//Sleep some:
lastUpdate += gameSpeed;
try {
Thread.sleep(Math
.max(0, lastUpdate - System.currentTimeMillis()));
} catch (Exception e) {
continue;
} finally {
lastUpdate = System.currentTimeMillis();
}
}
// level.pause();
}
}).start();
return true;
}
/**
* Initializes buttons.
*/
private void initializeButtons() {
pauseToggle = new LToggleButton();
pauseToggle.setImage(new AnimatedSprite(TileSetManager.getInstance()
.getTileSet("btn_pause"),
Direction.NO_DIRECTION,
Looping.NONE));
pauseToggle.addActionListener(this);
pauseToggle.setActionCommand("pause");
pauseToggle.setShown(true);
pauseToggle.setPosition(new Point(10, 110));
speedToggle = new LToggleButton();
speedToggle.setImage(new AnimatedSprite(TileSetManager.getInstance()
.getTileSet("btn_speedup"),
Direction.NO_DIRECTION,
Looping.NONE));
speedToggle.addActionListener(this);
speedToggle.setActionCommand("speedup");
speedToggle.setShown(true);
speedToggle.setPosition(new Point(10, 170));
nukeToggle = new LToggleButton();
nukeToggle.setImage(new AnimatedSprite(TileSetManager.getInstance()
.getTileSet("btn_nuke"),
Direction.NO_DIRECTION,
Looping.NONE));
nukeToggle.addActionListener(this);
nukeToggle.setActionCommand("nuke");
nukeToggle.setShown(true);
nukeToggle.setPosition(new Point(10, 230));
}
/**
* Initializes the labels.
*/
private void initializeLabels() {
timeLabel = new LFancyLabel();
timeLabel.setForeground(Color.yellow);
timeLabel.setFont(LFancyLabel.DEFAULT_FONT.deriveFont(Font.BOLD, 20.0f));
timeLabel.setText("");
timeLabel.setPosition(new Point(760, 50));
timeLabel.setShown(true);
releasedLabel = new LFancyLabel();
releasedLabel.setForeground(Color.yellow);
releasedLabel
.setFont(LFancyLabel.DEFAULT_FONT.deriveFont(Font.BOLD, 20.0f));
releasedLabel.setText("");
releasedLabel.setPosition(new Point(10, 50));
releasedLabel.setShown(true);
savedLabel = new LFancyLabel();
savedLabel.setForeground(Color.yellow);
savedLabel.setFont(LFancyLabel.DEFAULT_FONT.deriveFont(Font.BOLD, 20.0f));
savedLabel.setText("");
savedLabel.setPosition(new Point(10, 70));
savedLabel.setShown(true);
outLabel = new LFancyLabel();
outLabel.setForeground(Color.yellow);
outLabel.setFont(LFancyLabel.DEFAULT_FONT.deriveFont(Font.BOLD, 20.0f));
outLabel.setText("");
outLabel.setPosition(new Point(10, 90));
outLabel.setShown(true);
lblLemmingFlow = new LFancyLabel();
lblLemmingFlow.setForeground(Color.black);
lblLemmingFlow.setFont(LFancyLabel
.DEFAULT_FONT.deriveFont(Font.BOLD, 20.0f));
lblLemmingFlow.setText("");
lblLemmingFlow.setPosition(new Point(20, 360));
lblLemmingFlow.setShown(true);
}
/**
* Whatever else needs to be initialized.
*/
protected void specialInitialize() { }
/**
* Describe <code>updateStuff</code> method here.
*
*/
protected void updateStuff() {
//Update UI:
timeLabel.setText(Long.toString(level.getTimeRemaining() / 1000));
releasedLabel.setText("Released: "
+ Integer.toString(numReleasedLemmings)
+ "/" + strNumLemmings);
savedLabel.setText("Saved: "
+ Integer.toString(level.getLemmingsSaved())
+ "/" + strLemmingsToSave);
outLabel.setText("Out: "
+ Integer.toString(numLemmingsOut));
lblLemmingFlow.setText(Integer
.toString(101 - level.getLemmingFlow()));
jobs.updateButtons();
specialUpdate();
renderer.updateCursor();
}
/**
* Handles the special update.
*/
protected void specialUpdate() { }
//@roseuid 4066242E013C
/**
* This method will perform all of the necessary clean up operations
* once the object is no longer needed.
*
* @return boolean
*
*/
public boolean cleanUp() {
killed = true;
level = null;
return true;
}
/**
*This method will set the gamespeed;
*@param speed for gamespeed
*/
public void setGameSpeed(long speed) {
gameSpeed = speed;
}
/**
* Ends the level and goes on to the next state.
*/
public void endLevel() {
//Go to the level results state:
level.pause();
GameEngine.getInstance().setCurrentState(new LevelResultsState(level));
}
/**
* Handles it when the pause button is pressed.
*/
protected void handlePauseButton() {
singlePauseButtonHandle();
specialPauseHandle();
}
/**
* Describe <code>singlePauseButtonHandle</code> method here.
*
*/
protected void singlePauseButtonHandle() {
boolean p = pauseToggle.isSelected();
if (p) {
//We have paused:
level.pause();
} else {
//We have unpaused:
level.unpause();
}
}
/**
* Describe <code>getPauseButton</code> method here.
*
* @return a <code>LToggleButton</code> value
*/
protected LToggleButton getPauseButton() {
return pauseToggle;
}
/**
* Whatever else needs to be done for pause.
*/
protected void specialPauseHandle() { }
/**
* Handles it when the speedup button is pressed.
*/
protected void handleSpeedupButton() {
singleSpeedupButtonHandle();
specialSpeedupHandle();
}
/**
* Describe <code>singleSpeedupButtonHandle</code> method here.
*
*/
protected void singleSpeedupButtonHandle() {
boolean s = speedToggle.isSelected();
if (s) {
//We speed up:
//NOTE here that the name of the variable "gameSpeed" is a
//little misleading. It's really the delay between
//updates. Hence, when we want to speed up, we decrease this
//gamespeed.
gameSpeed /= 10;
} else {
//We slow down:
gameSpeed *= 10;
}
//Update the Level's notion of time:
level.setTimeIncrement(gameSpeed);
}
/**
* Whatever else needs to be done for speedup.
*/
protected void specialSpeedupHandle() { }
/**
* Handles it when the nuke button is pressed.
*/
protected void handleNukeButton() {
singleNukeButtonHandle();
specialNukeHandle();
}
/**
* Describe <code>singleNukeButtonHandle</code> method here.
*
*/
protected void singleNukeButtonHandle() {
boolean n = nukeToggle.isSelected();
if (n) {
//Gotta Nuke:
level.nukeEmALL();
} else {
//We are already nukin'
nukeToggle.toggleSelected();
}
}
/**
* Whatever else needs to be done for nuke.
*/
protected void specialNukeHandle() { }
/**
* Handles it when the increase button is pressed.
*/
protected void handleIncreaseButton() {
singleIncreaseButtonHandle();
specialIncreaseHandle();
}
/**
* Describe <code>singleIncreaseButtonHandle</code> method here.
*
*/
protected void singleIncreaseButtonHandle() {
level.increaseLemmingFlow();
}
/**
* Whatever else needs to be done for increase.
*/
protected void specialIncreaseHandle() { }
/**
* Handles it when the decrease button is pressed.
*/
protected void handleDecreaseButton() {
singleDecreaseButtonHandle();
specialDecreaseHandle();
}
/**
* Describe <code>singleDecreaseButtonHandle</code> method here.
*
*/
protected void singleDecreaseButtonHandle() {
level.decreaseLemmingFlow();
}
/**
* Whatever else needs to be done for decrease.
*/
protected void specialDecreaseHandle() { }
//@roseuid 4066242E016E
/**
* This function essentially processes the action event that may
* have been thrown by the UI.
*
* @param ae ae
*/
public void actionPerformed(ActionEvent ae) {
String a = ae.getActionCommand();
if (a.equals("pause")) {
handlePauseButton();
} else if (a.equals("speedup")) {
handleSpeedupButton();
} else if (a.equals("nuke")) {
handleNukeButton();
} else if (a.equals("increase")) {
handleIncreaseButton();
} else if (a.equals("decrease")) {
handleDecreaseButton();
}
}
/**
* Describe <code>isPauseSelected</code> method here.
*
* @return a <code>boolean</code> value
*/
protected boolean isPauseSelected() {
return pauseToggle.isSelected();
}
/**
* Describe <code>getGameSpeed</code> method here.
*
* @return an <code>int</code> value
*/
protected int getGameSpeed() {
return (int) gameSpeed;
}
/**
* Describe <code>getLemmingFlow</code> method here.
*
* @return an <code>int</code> value
*/
protected int getLemmingFlow() {
return (int) level.getLemmingFlow();
}
/**
* Listens to keys and stuff.
*/
private abstract class LKeyListener
extends LLeafComponent implements ITypable {
/**
* Deep-copies self <b>into the component</b> passed in.
*
* @param component a <code>LComponent</code> value
*/
protected void copy(LComponent component) {
}
/**
* Performs all of the necessary drawing for this control only. The
* children will be taken care of separately. This method need not
* concern itself with them.
*
* @param g a <code>Graphics</code> value
* @return a <code>boolean</code> value
*/
protected boolean paint(Graphics g) {
return true;
}
}
/**
*accessor for gpp
*@return GamePlayPanel
*/
public GamePlayPanel getGamePlayPanel() {
return gpp;
}
}

View File

@@ -0,0 +1,502 @@
package edu.gatech.cs2335.lemmings.engine;
import java.awt.Font;
import java.awt.event.ActionEvent;
//import java.awt.Point;
import java.awt.Color;
//import java.awt.Rectangle;
//import java.awt.Graphics;
//import edu.gatech.cs2335.lemmings.engine.lemmingjob.LemmingJobSettings;
import edu.gatech.cs2335.lemmings.graphics.Looping;
import edu.gatech.cs2335.lemmings.graphics.Direction;
import edu.gatech.cs2335.lemmings.graphics.AnimatedSprite;
import edu.gatech.cs2335.lemmings.graphics.TileSetManager;
//import edu.gatech.cs2335.lemmings.gui.ITypable;
//import edu.gatech.cs2335.lemmings.gui.LLeafComponent;
//import edu.gatech.cs2335.lemmings.gui.LComponent;
//import edu.gatech.cs2335.lemmings.gui.JobContainer;
import edu.gatech.cs2335.lemmings.gui.LRootPane;
import edu.gatech.cs2335.lemmings.gui.LButton;
//import edu.gatech.cs2335.lemmings.gui.LToggleButton;
import edu.gatech.cs2335.lemmings.gui.LFancyLabel;
//import edu.gatech.cs2335.lemmings.gui.GamePlayPanel;
//import edu.gatech.cs2335.lemmings.graphics.Renderer;
//import edu.gatech.cs2335.lemmings.physics.PhysicsEngine;
//import edu.gatech.cs2335.lemmings.file.LevelReader;
import java.awt.Point;
//import java.awt.event.ActionEvent;
import edu.gatech.cs2335.lemmings.gui.LIcon;
//import edu.gatech.cs2335.lemmings.gui.LButton;
//import edu.gatech.cs2335.lemmings.gui.LRootPane;
//import edu.gatech.cs2335.lemmings.graphics.Looping;
//import edu.gatech.cs2335.lemmings.graphics.Direction;
//import edu.gatech.cs2335.lemmings.graphics.AnimatedSprite;
//import edu.gatech.cs2335.lemmings.graphics.TileSetManager;
/**
* Class HelpState: Help screen...
*
* <PRE>
* Revision History:
* v1.0 (Apr. 21, 2004) - Created the HelpState class
* </PRE>
*
* @author <A HREF="mailto:gtg284h@mail.gatech.edu">Andrew Knight</A>
* @version Version 1.0, Apr. 21, 2004
*/
public class HelpState extends AbstractGameState {
/**
* Display debug information?
*/
public static final boolean VERBOSE = false;
/**
* The label to display Help title.
*/
private LFancyLabel title;
/**
* The label to display Help subtitle.
*/
private LFancyLabel subTitle;
/**
* The label to display singleplayer info.
*/
private LFancyLabel single;
/**
* The label to display singleplayer info.
*/
private LFancyLabel singlet;
/**
* The label to display multiplayer info.
*/
private LFancyLabel multi;
/**
* The label to display multiplayer info.
*/
private LFancyLabel multit;
/**
* The label to display hostbox info.
*/
private LFancyLabel hostBox;
/**
* The label to display hostbox info.
*/
private LFancyLabel hostBoxt;
/**
* The label to display portbox info.
*/
private LFancyLabel portBox;
/**
* The label to display portbox info.
*/
private LFancyLabel portBoxt;
/**
* The label to display hostButton info.
*/
private LFancyLabel hostButton;
/**
* The label to display hostButton info.
*/
private LFancyLabel hostButtont;
/**
* The label to display connectButton info.
*/
private LFancyLabel connectButton;
/**
* The label to display connectButton info.
*/
private LFancyLabel connectButtont;
/**
* The label to display credits info.
*/
private LFancyLabel credits;
/**
* The label to display credits info.
*/
private LFancyLabel creditst;
/**
* The label to display help info.
*/
private LFancyLabel help;
/**
* The label to display help info.
*/
private LFancyLabel helpt;
/**
* The label to display quit info.
*/
private LFancyLabel quit;
/**
* The label to display quit info.
*/
private LFancyLabel quitt;
/**
* The label to display back info.
*/
private LFancyLabel back;
/**
* The label to display back info.
*/
private LFancyLabel backt;
/**
* The label to display mainmenu info.
*/
private LFancyLabel mainMenu;
/**
* The label to display mainmenu info.
*/
private LFancyLabel mainMenut;
/**
* The label to other gameplay info.
*/
private LFancyLabel gamePlay;
/**
* Creates a new <code>HelpState</code> instance.
*/
public HelpState() {
//Initialize background:
LIcon bg = new LIcon(TileSetManager.getInstance()
.getTileSet("background"));
bg.setShown(true);
bg.setPosition(new Point(0, 0));
title = new LFancyLabel();
title.setForeground(Color.black);
title.setFont(LFancyLabel.DEFAULT_FONT.deriveFont(Font.BOLD, 35.0f));
title.setShown(true);
subTitle = new LFancyLabel();
subTitle.setForeground(Color.black);
subTitle.setFont(LFancyLabel.DEFAULT_FONT.deriveFont(Font.BOLD, 18.0f));
subTitle.setShown(true);
single = new LFancyLabel();
single.setForeground(Color.black);
single.setFont(LFancyLabel.DEFAULT_FONT.deriveFont(Font.BOLD, 18.0f));
single.setShown(true);
singlet = new LFancyLabel();
singlet.setForeground(Color.black);
singlet.setFont(LFancyLabel.DEFAULT_FONT.deriveFont(Font.PLAIN, 16.0f));
singlet.setShown(true);
multi = new LFancyLabel();
multi.setForeground(Color.black);
multi.setFont(LFancyLabel.DEFAULT_FONT.deriveFont(Font.BOLD, 18.0f));
multi.setShown(true);
multit = new LFancyLabel();
multit.setForeground(Color.black);
multit.setFont(LFancyLabel.DEFAULT_FONT.deriveFont(Font.PLAIN, 16.0f));
multit.setShown(true);
hostBox = new LFancyLabel();
hostBox.setForeground(Color.black);
hostBox.setFont(LFancyLabel.DEFAULT_FONT.deriveFont(Font.BOLD, 14.0f));
hostBox.setShown(true);
hostBoxt = new LFancyLabel();
hostBoxt.setForeground(Color.black);
hostBoxt.setFont(LFancyLabel.DEFAULT_FONT.deriveFont(Font.PLAIN, 12.0f));
hostBoxt.setShown(true);
portBox = new LFancyLabel();
portBox.setForeground(Color.black);
portBox.setFont(LFancyLabel.DEFAULT_FONT.deriveFont(Font.BOLD, 14.0f));
portBox.setShown(true);
portBoxt = new LFancyLabel();
portBoxt.setForeground(Color.black);
portBoxt.setFont(LFancyLabel.DEFAULT_FONT.deriveFont(Font.PLAIN, 12.0f));
portBoxt.setShown(true);
hostButton = new LFancyLabel();
hostButton.setForeground(Color.black);
hostButton.setFont(LFancyLabel.DEFAULT_FONT.deriveFont(Font.BOLD, 14.0f));
hostButton.setShown(true);
hostButtont = new LFancyLabel();
hostButtont.setForeground(Color.black);
hostButtont.setFont(LFancyLabel.DEFAULT_FONT.deriveFont(Font.PLAIN, 12.0f));
hostButtont.setShown(true);
connectButton = new LFancyLabel();
connectButton.setForeground(Color.black);
connectButton.setFont(
LFancyLabel.DEFAULT_FONT.deriveFont(Font.BOLD, 14.0f));
connectButton.setShown(true);
connectButtont = new LFancyLabel();
connectButtont.setForeground(Color.black);
connectButtont.setFont(
LFancyLabel.DEFAULT_FONT.deriveFont(Font.PLAIN, 12.0f));
connectButtont.setShown(true);
credits = new LFancyLabel();
credits.setForeground(Color.black);
credits.setFont(LFancyLabel.DEFAULT_FONT.deriveFont(Font.BOLD, 18.0f));
credits.setShown(true);
creditst = new LFancyLabel();
creditst.setForeground(Color.black);
creditst.setFont(LFancyLabel.DEFAULT_FONT.deriveFont(Font.PLAIN, 16.0f));
creditst.setShown(true);
help = new LFancyLabel();
help.setForeground(Color.black);
help.setFont(LFancyLabel.DEFAULT_FONT.deriveFont(Font.BOLD, 18.0f));
help.setShown(true);
helpt = new LFancyLabel();
helpt.setForeground(Color.black);
helpt.setFont(LFancyLabel.DEFAULT_FONT.deriveFont(Font.PLAIN, 16.0f));
helpt.setShown(true);
quit = new LFancyLabel();
quit.setForeground(Color.black);
quit.setFont(LFancyLabel.DEFAULT_FONT.deriveFont(Font.BOLD, 18.0f));
quit.setShown(true);
quitt = new LFancyLabel();
quitt.setForeground(Color.black);
quitt.setFont(LFancyLabel.DEFAULT_FONT.deriveFont(Font.PLAIN, 16.0f));
quitt.setShown(true);
back = new LFancyLabel();
back.setForeground(Color.black);
back.setFont(LFancyLabel.DEFAULT_FONT.deriveFont(Font.BOLD, 18.0f));
back.setShown(true);
backt = new LFancyLabel();
backt.setForeground(Color.black);
backt.setFont(LFancyLabel.DEFAULT_FONT.deriveFont(Font.PLAIN, 16.0f));
backt.setShown(true);
mainMenu = new LFancyLabel();
mainMenu.setForeground(Color.black);
mainMenu.setFont(LFancyLabel.DEFAULT_FONT.deriveFont(Font.BOLD, 18.0f));
mainMenu.setShown(true);
mainMenut = new LFancyLabel();
mainMenut.setForeground(Color.black);
mainMenut.setFont(LFancyLabel.DEFAULT_FONT.deriveFont(Font.PLAIN, 16.0f));
mainMenut.setShown(true);
gamePlay = new LFancyLabel();
gamePlay.setForeground(Color.black);
gamePlay.setFont(LFancyLabel.DEFAULT_FONT.deriveFont(Font.PLAIN, 18.0f));
gamePlay.setShown(true);
//Initialize button:
LButton goOn = new LButton();
goOn.setPosition(new Point(10, 590));
goOn.setImage(new AnimatedSprite(TileSetManager.getInstance()
.getTileSet("mpb_back"),
Direction.NO_DIRECTION, Looping.NONE));
goOn.addActionListener(this);
goOn.setActionCommand("goOn");
goOn.setShown(true);
//Initialize UI:
LRootPane np = new LRootPane();
np.addChild(bg);
np.addChild(goOn);
np.addChild(title);
np.addChild(subTitle);
np.addChild(single);
np.addChild(singlet);
np.addChild(multi);
np.addChild(multit);
np.addChild(hostBox);
np.addChild(hostBoxt);
np.addChild(portBox);
np.addChild(portBoxt);
np.addChild(hostButton);
np.addChild(hostButtont);
np.addChild(connectButton);
np.addChild(connectButtont);
np.addChild(credits);
np.addChild(creditst);
np.addChild(help);
np.addChild(helpt);
np.addChild(quit);
np.addChild(quitt);
np.addChild(back);
np.addChild(backt);
np.addChild(mainMenu);
np.addChild(mainMenut);
np.addChild(gamePlay);
setUI(np);
}
/**
* This method will initialize the state that it belongs to. It will
* then return true upon success, and false upon failure.
*
* @return boolean
*/
public boolean initialize() {
title.setText("Help");
title.setPosition(new Point(30, 80));
subTitle.setText("Menu Navigation:");
subTitle.setPosition(new Point(65, 125));
single.setText("\"SinglePlayer\" Button:");
single.setPosition(new Point(100, 165));
singlet.setText("Starts a SinglePlayer game");
singlet.setPosition(new Point(302, 165));
multi.setText("\"MultiPlayer\" Button:");
multi.setPosition(new Point(100, 205));
multit.setText("Starts a MultiPlayer game");
multit.setPosition(new Point(290, 205));
hostBox.setText("\"Host\" TextField:");
hostBox.setPosition(new Point(135, 230));
hostBoxt.setText("IP address of host");
hostBoxt.setPosition(new Point(260, 230));
portBox.setText("\"Port\" TextField:");
portBox.setPosition(new Point(135, 255));
portBoxt.setText("Port on host");
portBoxt.setPosition(new Point(260, 255));
hostButton.setText("\"Host\" Button:");
hostButton.setPosition(new Point(135, 280));
hostButtont.setText("Hosts a multiplayer session");
hostButtont.setPosition(new Point(247, 280));
connectButton.setText("\"Connect\" Button:");
connectButton.setPosition(new Point(135, 302));
connectButtont.setText("Connects to a multiplayer session");
connectButtont.setPosition(new Point(270, 302));
credits.setText("\"Credits\" Button:");
credits.setPosition(new Point(100, 330));
creditst.setText("Displays information about the creators");
creditst.setPosition(new Point(255, 330));
help.setText("\"Help\" Button:");
help.setPosition(new Point(100, 365));
helpt.setText("Displays this screen");
helpt.setPosition(new Point(233, 365));
quit.setText("\"Quit\" Button:");
quit.setPosition(new Point(100, 405));
quitt.setText("Exits the game");
quitt.setPosition(new Point(229, 405));
back.setText("\"Back\" Button:");
back.setPosition(new Point(100, 445));
backt.setText("Returns to previous menu");
backt.setPosition(new Point(236, 445));
mainMenu.setText("\"MainMenu\" Button:");
mainMenu.setPosition(new Point(100, 482));
mainMenut.setText("Returns to the main menu");
mainMenut.setPosition(new Point(280, 482));
gamePlay.setText("For help on game-play, refer to the html user manual.");
gamePlay.setPosition(new Point(200, 540));
if (VERBOSE) {
System.err.println("HelpState: I am initialized!");
System.err.flush();
}
return true;
}
/**
* This method will perform all of the necessary clean up operations
* once the object is no longer needed.
*
* @return boolean
*
*/
public boolean cleanUp() {
if (VERBOSE) {
System.err.println("HelprState: I am cleaned up!");
System.err.flush();
}
return true;
}
/**
* This function essentially processes the action event that may
* have been thrown by the UI.
*
* @param ae ae
*
*/
public void actionPerformed(ActionEvent ae) {
if (VERBOSE) {
System.err.println("HelpState: Got some action - "
+ ae.getActionCommand());
System.err.flush();
}
//Go back to the Multiplayer setup state:
GameEngine.getInstance().setCurrentState(new MainMenuState());
}
}

View File

@@ -0,0 +1,22 @@
package edu.gatech.cs2335.lemmings.engine;
/**
* Interface ICleanable: The implementing objects will be able to be
* cleaned up.
*
* <PRE>
* Revision History:
* v1.0 (Apr. 15, 2004) - Created the ICleanable interface
* </PRE>
*
* @author <A HREF="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</A>
* @version Version 1.0, Apr. 15, 2004
*/
public interface ICleanable {
/**
* Cleans up all references for the garbage collector.
*/
public void cleanUp();
}

View File

@@ -0,0 +1,133 @@
package edu.gatech.cs2335.lemmings.engine;
import edu.gatech.cs2335.lemmings.graphics.Direction;
import edu.gatech.cs2335.lemmings.physics.PhysicsObject;
import edu.gatech.cs2335.lemmings.engine.lemmingjob.LemmingJob;
import edu.gatech.cs2335.lemmings.engine.lemmingjob.LemmingJobFactory;
import edu.gatech.cs2335.lemmings.engine.lemmingjob.LemmingJobSettings;
/**
* Represents a generic lemming, that can move around, and do
* stuff. What exactly it does is decided by the lemming's occupation.
*
* @author <A HREF="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</A>
* @see LemmingJob
*/
public final class Lemming extends PhysicsObject implements ICleanable {
/**
* What the lemming does.
*/
private LemmingJob occupation;
/**
* The physics object associated with the lemming.
*/
//private PhysicsObject physics;
/**
* Creates a new <code>Lemming</code> instance.
*
*/
public Lemming() {
//Set up physics:
super();
//physics = new PhysicsObject();
//Set Occupation:
setOccupation(LemmingJobSettings.JOB_ID_WALKER);
}
/**
* Describe <code>cleanUp</code> method here.
*
*/
public void cleanUp() {
occupation.cleanUp();
occupation = null;
}
/**
* Access method for the occupation property.
*
* @return the current value of the occupation property
*/
public LemmingJob getOccupation() {
return occupation;
}
/**
* Sets the value of the occupation property.
*
* @param id the id of the occupation to give this lemming.
*/
public void setOccupation(String id) {
occupation = LemmingJobFactory.getInstance().makeJob(id);
occupation.setOwner(this);
updateDirection();
}
/**
* Describe <code>setOccupation</code> method here.
*
* @param job a <code>LemmingJob</code> value
*/
public void setOccupation(LemmingJob job) {
job.setOwner(this);
occupation = job;
updateDirection();
}
/**
* Access method for the physics property.
*
* @return the current value of the physics property
*/
public PhysicsObject getPhysics() {
//Should deprecate this. :( Really should.
return this;
// return physics;
}
/**
* This method should be called whenever the lemming's direction
* changes. It will update the current animation with the new
* direction of movement.
*/
public void updateDirection() {
int xVelocity = getVelocity().getI();
Direction dir;
if (xVelocity == 0) {
dir = Direction.NO_DIRECTION;
} else if (xVelocity < 0) {
dir = Direction.LEFT;
} else {
dir = Direction.RIGHT;
}
if (occupation.getRegularAnimation().getMovementDirection() != dir) {
occupation.getRegularAnimation().setMovementDirection(dir);
}
if (occupation.getFallingAnimation().getMovementDirection() != dir) {
occupation.getFallingAnimation().setMovementDirection(dir);
}
}
/**
* Returns a string representation of a lemming.
*
* @return a <code>String</code> value
*/
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("Lemming: (").append(occupation.getId()).append(")\n");
sb.append(toString()).append("\n");
return sb.toString();
}
}

View File

@@ -0,0 +1,47 @@
package edu.gatech.cs2335.lemmings.engine;
/**
* Class LemmingDrown: This pretty sprite is created when the lemming
* drowns.
*
* <PRE>
* Revision History:
* v1.0 (Apr. 14, 2004) - Created the LemmingDrown class
* </PRE>
*
* @author <A HREF="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</A>
* @version Version 1.0, Apr. 14, 2004
*/
public class LemmingDrown extends PrettySprite {
/**
* Creates a new <code>LemmingDrown</code> instance.
*/
public LemmingDrown() {
super("drown");
}
/**
* Should return true when the sprite is ready to kill self.
*
* @return a <code>boolean</code> value
*/
protected boolean canKillSelf() {
if (getAnimation().getCurrentFrame() == 0) {
//The animation is through.
//Create an angel:
PrettySprite a = new LemmingsSoul();
a.getPosition().setPoint(getPosition().getX(),
getPosition().getY(),
getPosition().getZ());
getLevel().addPrettySprite(a);
//We are done:
return true;
} else {
return false;
}
}
}

View File

@@ -0,0 +1,47 @@
package edu.gatech.cs2335.lemmings.engine;
/**
* Class LemmingSplat: When the lemming falls too far and smashes into
* the ground, this blood-splattering animation will be played.
*
* <PRE>
* Revision History:
* v1.0 (Apr. 12, 2004) - Created the LemmingSplat class
* </PRE>
*
* @author <A HREF="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</A>
* @version Version 1.0, Apr. 12, 2004
*/
public class LemmingSplat extends PrettySprite {
/**
* Creates a new <code>LemmingSplat</code> instance.
*/
public LemmingSplat() {
super("splat");
}
/**
* Should return true when the sprite is ready to kill self.
*
* @return a <code>boolean</code> value
*/
protected boolean canKillSelf() {
if (getAnimation().getCurrentFrame() == 0) {
//The animation is through.
//Create an angel:
PrettySprite a = new LemmingsSoul();
a.getPosition().setPoint(getPosition().getX(),
getPosition().getY(),
getPosition().getZ());
getLevel().addPrettySprite(a);
//We are done:
return true;
} else {
return false;
}
}
}

View File

@@ -0,0 +1,39 @@
package edu.gatech.cs2335.lemmings.engine;
/**
* Class LemmingsSoul: You have failed, The lemming is DEAD, His soul
* goes to heaven.
*
* <PRE>
* Revision History:
* v1.0 (Apr. 11, 2004) - Created the LemmingsSoul class
* </PRE>
*
* @author <A HREF="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</A>
* @version Version 1.0, Apr. 11, 2004
*/
public class LemmingsSoul extends PrettySprite {
/**
* Creates a new <code>LemmingsSoul</code> instance.
*/
public LemmingsSoul() {
super("angel");
}
/**
* Should return true when the sprite is ready to kill self.
*
* @return a <code>boolean</code> value
*/
protected boolean canKillSelf() {
if (getPosition().getY() <= 5) {
//We are almost at the top of the screen... That's close enough.
return true;
}
return false;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,386 @@
package edu.gatech.cs2335.lemmings.engine;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.Vector;
import edu.gatech.cs2335.lemmings.engine.lemmingjob.LemmingJobSettings;
/**
* This class contains the data associated with a certain level. It is
* essentially your template to create playable levels.
*
* @author <A HREF="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</A>
*/
public class LevelData {
/**
* The thumbnail to display for the level.
*/
private BufferedImage thumbnail;
/**
* The id of the level. This is essentially the name of the
* directory that the file was loaded from.
*/
private String id;
/**
* The name of the level.
*/
private String name;
/**
* The number of lemmings initially let out in the level.
*/
private int numLemmings;
/**
* The percentage of lemmings we need to save. Needs to be between 0 and 1.
*/
private int percentToSave;
/**
* The time limit for the level.
*/
private long timeLimit;
/**
* The position of the entrance point on the map.
*/
private Point entrancePoint;
/**
* The position of the exit point on the map.
*/
private Point exitPoint;
/**
* The list of all portals available in this level.
*/
private List portals;
/**
* This map will contain the number of jobs of each type available
* for the level.
*/
private Map jobMap;
/**
* The level of water on the level. Uhhh, yeah. -1 means there is no
* water on the level.
*/
private int waterLevel;
/**
* The lines of the briefing to display before the level.
*/
private String[] mapBriefing;
/**
* The lines of the win statement to display after the level.
*/
private String[] winStatement;
/**
* Creates a new <code>LevelData</code> instance.
*
*/
public LevelData() {
thumbnail = null;
entrancePoint = new Point(0, 0);
exitPoint = new Point(0, 0);
jobMap = new HashMap(LemmingJobSettings.ALL_JOB_NAMES.length);
portals = new Vector();
name = "";
numLemmings = 0;
percentToSave = 0;
timeLimit = 0;
waterLevel = -1;
mapBriefing = null;
winStatement = null;
}
/**
* Access method for the thumbnail property.
*
* @return the current value of the thumbnail property
*/
public BufferedImage getThumbnail() {
return thumbnail;
}
/**
* Sets the value of the thumbnail property.
*
* @param aThumbnail the new value of the thumbnail property
*/
public void setThumbnail(BufferedImage aThumbnail) {
thumbnail = aThumbnail;
}
/**
* Access method for the name property.
*
* @return the current value of the name property
*/
public String getName() {
return name;
}
/**
* Sets the value of the name property.
*
* @param aName the new value of the name property
*/
public void setName(String aName) {
name = aName;
}
/**
* Access method for the id property.
*
* @return the current value of the id property
*/
public String getId() {
return id;
}
/**
* Sets the value of the id property.
*
* @param aId the new value of the id property
*/
public void setId(String aId) {
id = aId;
}
/**
* Access method for the numLemmings property.
*
* @return the current value of the numLemmings property
*/
public int getNumLemmings() {
return numLemmings;
}
/**
* Sets the value of the numLemmings property.
*
* @param aNumLemmings the new value of the numLemmings property
*/
public void setNumLemmings(int aNumLemmings) {
numLemmings = aNumLemmings;
}
/**
* Access method for the percentToSave property.
*
* @return the current value of the percentToSave property
*/
public int getPercentToSave() {
return percentToSave;
}
/**
* Sets the value of the percentToSave property.
*
* @param aPercentToSave the new value of the percentToSave property
*/
public void setPercentToSave(int aPercentToSave) {
percentToSave = aPercentToSave;
}
/**
* Access method for the timeLimit property.
*
* @return the current value of the timeLimit property
*/
public long getTimeLimit() {
return timeLimit;
}
/**
* Sets the value of the timeLimit property.
*
* @param aTimeLimit the new value of the timeLimit property
*/
public void setTimeLimit(long aTimeLimit) {
timeLimit = aTimeLimit;
}
/**
* Get the value of entrancePoint.
* @return value of entrancePoint.
*/
public Point getEntrancePoint() {
return entrancePoint;
}
/**
* Set the value of entrancePoint.
* @param v Value to assign to entrancePoint.
*/
public void setEntrancePoint(Point v) {
this.entrancePoint = v;
}
/**
* Set the value of entrancePoint.
* @param x an <code>int</code> value
* @param y an <code>int</code> value
*/
public void setEntrancePoint(int x, int y) {
this.entrancePoint.x = x;
this.entrancePoint.y = y;
}
/**
* Get the value of exitPoint.
* @return value of exitPoint.
*/
public Point getExitPoint() {
return exitPoint;
}
/**
* Set the value of exitPoint.
* @param v Value to assign to exitPoint.
*/
public void setExitPoint(Point v) {
this.exitPoint = v;
}
/**
* Set the value of exitPoint.
* @param x an <code>int</code> value
* @param y an <code>int</code> value
*/
public void setExitPoint(int x, int y) {
this.exitPoint.x = x;
this.exitPoint.y = y;
}
/**
* Get the value of waterLevel.
* @return value of waterLevel.
*/
public int getWaterLevel() {
return waterLevel;
}
/**
* Set the value of waterLevel. Note that -1 is a magic value which
* means there is no water on the level. Other negative numbers will
* be ABSed before application.
* @param v Value to assign to waterLevel.
*/
public void setWaterLevel(int v) {
if (v < -1) {
this.waterLevel = -v;
} else {
this.waterLevel = v;
}
}
/**
* Adds the number of jobs for the appropriate job id for the level.
*
* @param idd a <code>String</code> value
* @param num an <code>int</code> value
*/
public void addJob(String idd, int num) {
jobMap.put(idd, new Integer(num));
}
/**
* Returns the number of jobs of the specified type for this level.
*
* @param idd a <code>String</code> value
* @return an <code>int</code> value
*/
public int getNumJobs(String idd) {
if (!jobMap.containsKey(idd)) { return 0; }
Integer i = (Integer) jobMap.get(idd);
return i.intValue();
}
/**
* Returns the job map.
*
* @return a <code>Map</code> value
*/
public Map getJobMap() {
return jobMap;
}
/**
* Sets the job map
* @param jm , map of jobs to set
*/
public void setJobMap(Map jm) {
jobMap = jm;
}
/**
* Describe <code>getPortals</code> method here.
*
* @return a <code>List</code> value
*/
public List getPortals() {
return portals;
}
/**
* Describe <code>addPortal</code> method here.
*
* @param type a <code>String</code> value
* @param value a <code>String</code> value
*/
public void addPortal(String type, String value) {
Portal p = PortalFactory.getInstance().makePortal(type, value);
if (p != null) {
portals.add(p);
if (type.equals(PortalFactory.PORTAL_TYPES[0])) {
entrancePoint.x = p.getPhysics().getPosition().getX();
entrancePoint.y = p.getPhysics().getPosition().getY();
} else if (type.equals(PortalFactory.PORTAL_TYPES[1])) {
exitPoint.x = p.getPhysics().getPosition().getX();
exitPoint.y = p.getPhysics().getPosition().getY();
}
}
}
/**
* Returns the string representation of the level.
*
* @return a <code>String</code> value
*/
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("Level (").append(getId()).append(")\n");
sb.append("\tName: ").append(getName()).append("\n");
sb.append("\tLemmings: ").append(getNumLemmings()).append("\n");
sb.append("\tSave: ").append(getPercentToSave() * 100).append("%\n");
sb.append("\tTime Limit: ").append(getTimeLimit()).append(" sec\n");
sb.append("\tEntrance: (").append(getEntrancePoint().x)
.append(", ").append(getEntrancePoint().y).append(")\n");
sb.append("\tExit: (").append(getExitPoint().x)
.append(", ").append(getExitPoint().y).append(")\n");
return sb.toString();
}
}

View File

@@ -0,0 +1,33 @@
package edu.gatech.cs2335.lemmings.engine;
/**
* Class LevelEntrance: This is where lemmings enter a level.
*
* <PRE>
* Revision History:
* v1.0 (Mar. 28, 2004) - Created the LevelEntrance class
* </PRE>
*
* @author <A HREF="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</A>
* @version Version 1.0, Mar. 28, 2004
*/
public class LevelEntrance extends Portal {
/**
* Creates a new <code>LevelEntrance</code> instance.
*/
public LevelEntrance() {
super(PortalFactory.PORTAL_TYPES[0]);
}
/**
* This function will be called when a lemming enters this portal.
*
* @param l a <code>Lemming</code> value
*/
public void processLemmingEntry(Lemming l) {
//This is an *entry* nothing to do with the lemming.
}
}

View File

@@ -0,0 +1,39 @@
package edu.gatech.cs2335.lemmings.engine;
/**
* Class LevelExit: This is where lemmings exit a level.
*
* <PRE>
* Revision History:
* v1.0 (Mar. 28, 2004) - Created the LevelExit class
* </PRE>
*
* @author <A HREF="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</A>
* @version Version 1.0, Mar. 28, 2004
*/
public class LevelExit extends Portal {
/**
* Creates a new <code>LevelExit</code> instance.
*/
public LevelExit() {
super(PortalFactory.PORTAL_TYPES[1]);
}
/**
* This function will be called when a lemming enters this portal.
*
* @param l a <code>Lemming</code> value
*/
public void processLemmingEntry(Lemming l) {
//This lemming has been saved. Wohoo!
if (GameEngine.VERBOSE) {
System.out.println("Homie's home (aka a Lemming has been saved)");
System.out.flush();
}
getParent().killLemming(l, true);
}
}

View File

@@ -0,0 +1,263 @@
package edu.gatech.cs2335.lemmings.engine;
import java.awt.Font;
//import java.awt.Color;
import java.awt.Point;
import java.awt.event.ActionEvent;
//import java.util.Random;
import edu.gatech.cs2335.lemmings.file.LevelReader;
import edu.gatech.cs2335.lemmings.gui.LIcon;
import edu.gatech.cs2335.lemmings.gui.LButton;
import edu.gatech.cs2335.lemmings.gui.LLabel;
import edu.gatech.cs2335.lemmings.gui.LFancyLabel;
import edu.gatech.cs2335.lemmings.gui.LRootPane;
import edu.gatech.cs2335.lemmings.graphics.Looping;
import edu.gatech.cs2335.lemmings.graphics.Direction;
import edu.gatech.cs2335.lemmings.graphics.AnimatedSprite;
import edu.gatech.cs2335.lemmings.graphics.TileSetManager;
/**
* Class LevelResultsState: Shows the results of a level.
*
* <PRE>
* Revision History:
* v1.0 (Apr. 14, 2004) - Created the LevelResultsState class
* </PRE>
*
* @author <A HREF="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</A>
* @version Version 1.0, Apr. 14, 2004
*/
public class LevelResultsState extends AbstractGameState {
/**
* Show debug output?
*/
private static final boolean VERBOSE = false;
/**
* The level, whose results we are showing.
*/
private Level level;
/**
* Contains the name of the level.
*/
private LFancyLabel lblLevelName;
/**
* Something to show when the user has won/lost.
*/
private LLabel[] lblSayings;
/**
* How many lemmings were saved.
*/
private LLabel lblLemmingsSaved;
/**
* How many lemmings were not saved.
*/
private LLabel lblLemmingsKilled;
/**
* How much time did it take?
*/
private LLabel lblTimeTaken;
/**
* Describe variable <code>lemmingsSaved</code> here.
*
*/
private int lemmingsSaved;
/**
* Describe variable <code>lemmingsToSave</code> here.
*
*/
private int lemmingsToSave;
/**
* Creates a new <code>LevelResultsState</code> instance.
*@param l len
*/
public LevelResultsState(Level l) {
level = l;
}
/**
* This method will initialize the state that it belongs to. It will
* then return true upon success, and false upon failure.
*
* @return boolean
*/
public boolean initialize() {
LRootPane np = new LRootPane();
LIcon bg = new LIcon(TileSetManager.getInstance().getTileSet("bg_result"));
bg.setShown(true);
bg.setPosition(new Point(0, 0));
//Buttons:
LButton back = new LButton();
back
.setImage(new AnimatedSprite(TileSetManager.getInstance()
.getTileSet("rb_back"),
Direction.NO_DIRECTION,
Looping.NONE));
back.setPosition(new Point(10, 590));
back.setShown(true);
back.setActionCommand("back");
back.addActionListener(this);
LButton play = new LButton();
play
.setImage(new AnimatedSprite(TileSetManager.getInstance()
.getTileSet("rb_play"),
Direction.NO_DIRECTION,
Looping.NONE));
play.setPosition(new Point(680, 590));
play.setShown(true);
play.setActionCommand("play");
play.addActionListener(this);
//Labels:
lblLevelName = new LFancyLabel();
lblLevelName.setFont(LFancyLabel.DEFAULT_FONT
.deriveFont(Font.BOLD, 30.0f));
lblLevelName.setText(level.getData().getName());
lblLevelName.setPosition(new Point(250, 180));
lblLevelName.setShown(true);
//TODOXC: Set this to whatever it needs to be eventually.
lblSayings = null;
lemmingsSaved = level.getLemmingsSaved();
lemmingsToSave = level.getData().getPercentToSave();
lemmingsToSave *= level.getData().getNumLemmings();
lemmingsToSave /= 100;
lblLemmingsSaved = new LLabel();
lblLemmingsSaved.setText("Lemmings Saved: " + lemmingsSaved
+ "/" + lemmingsToSave);
lblLemmingsSaved.setPosition(new Point(300, 220));
lblLemmingsSaved.setShown(true);
lblLemmingsKilled = new LLabel();
lblLemmingsKilled
.setText("Lemmings Dead: "
+ Math.max(level.getData().getNumLemmings()
- level.getLemmingsSaved(), 0));
lblLemmingsKilled.setPosition(new Point(300, 240));
lblLemmingsKilled.setShown(true);
lblTimeTaken = new LLabel();
lblTimeTaken
.setText("Time Taken: "
+ (level.getData().getTimeLimit()
- (level.getTimeRemaining() / 1000)));
lblTimeTaken.setPosition(new Point(300, 260));
lblTimeTaken.setShown(true);
np.addChild(bg);
np.addChild(lblLevelName);
np.addChild(lblLemmingsSaved);
np.addChild(lblLemmingsKilled);
np.addChild(lblTimeTaken);
np.addChild(back);
np.addChild(play);
setUI(np);
return true;
}
/**
* This method will perform all of the necessary clean up operations
* once the object is no longer needed.
*
* @return boolean
*
*/
public boolean cleanUp() {
level.cleanUp();
level = null;
return true;
}
/**
* This function essentially processes the action event that may
* have been thrown by the UI.
*
* @param ae ae
*
*/
public void actionPerformed(ActionEvent ae) {
String a = ae.getActionCommand();
if (a.equals("back")) {
//Go back to the main menu:
GameEngine.getInstance().setCurrentState(new MainMenuState());
} else if (a.equals("play")) {
//Load next level if this one was passed, and this level, if it
//was failed.
String name = level.getData().getId();
if (VERBOSE) {
System.out.println("LevelResultsState: Want to play again...");
System.out.println("\tLemmings Saved: " + lemmingsSaved);
System.out.println("\tRequired to Advance: " + lemmingsToSave);
System.out.flush();
}
if (lemmingsSaved >= lemmingsToSave) {
//The player saved enough lemmings.
String nextLevel = LevelReader.getInstance().findNextLevel(name);
if (nextLevel == null) {
//Went through all levels...
//Show some kind of "You Win!" screen????? Would be
//good. But it's too late now.
GameEngine.getInstance().setCurrentState(new MainMenuState());
} else {
//Go to the next level:
GameEngine.getInstance().startSingleLevel(nextLevel);
}
} else {
//Go to same level:
GameEngine.getInstance().startSingleLevel(name);
}
}
}
/**
* Describe <code>getLevel</code> method here.
*
* @return a <code>Level</code> value
*/
public Level getLevel() {
return level;
}
/**
* Describe <code>setLevel</code> method here.
*
* @param l a <code>Level</code> value
*/
public void setLevel(Level l) {
level = l;
}
}

View File

@@ -0,0 +1,143 @@
package edu.gatech.cs2335.lemmings.engine;
import java.awt.Point;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import edu.gatech.cs2335.lemmings.gui.LIcon;
import edu.gatech.cs2335.lemmings.gui.LButton;
import edu.gatech.cs2335.lemmings.gui.LRootPane;
import edu.gatech.cs2335.lemmings.gui.LevelContainer;
import edu.gatech.cs2335.lemmings.graphics.Looping;
import edu.gatech.cs2335.lemmings.graphics.Direction;
import edu.gatech.cs2335.lemmings.graphics.AnimatedSprite;
import edu.gatech.cs2335.lemmings.graphics.TileSetManager;
import edu.gatech.cs2335.lemmings.file.LevelReader;
/**
* This is the main menu state. It displays the main menu stuff, which
* allows the player to select to play the single player game, the
* multiplayer game, or quit.
*
* @author <A HREF="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</A>
*/
public class LevelSelectionState extends AbstractGameState {
/**
* The container with the levels.
*/
private LevelContainer container;
/**
* Creates a new <code>LevelSelectionState</code> instance.
*
*/
public LevelSelectionState() {
//Make sure that the resources we want are loaded:
TileSetManager.getInstance().getTileSet("background");
}
//@roseuid 4065D29D005F
/**
* This method will initialize the state that it belongs to. It will
* then return true upon success, and false upon failure.
*
* @return boolean
*
*/
public boolean initialize() {
//Initialize background:
LIcon bg = new LIcon(TileSetManager.getInstance()
.getTileSet("background"));
bg.setShown(true);
bg.setPosition(new Point(0, 0));
//Initialize Levels:
container = new LevelContainer();
String[] levels = LevelReader.getInstance().getLevelList();
container.setShown(true);
container.setPosition(new Point(20, 40));
container.setSize(new Dimension(770, 500));
for (int i = 0; i < levels.length; i++) {
container.addLevelButton(levels[i]);
}
//Initialize buttons:
LButton back = new LButton();
back
.setImage(new AnimatedSprite(TileSetManager.getInstance()
.getTileSet("lb_back"),
Direction.NO_DIRECTION,
Looping.NONE));
back.setPosition(new Point(10, 590));
back.setShown(true);
back.setActionCommand("back");
back.addActionListener(this);
LButton play = new LButton();
play
.setImage(new AnimatedSprite(TileSetManager.getInstance()
.getTileSet("lb_play"),
Direction.NO_DIRECTION,
Looping.NONE));
play.setPosition(new Point(680, 590));
play.setShown(true);
play.setActionCommand("play");
play.addActionListener(this);
//Initialize UI:
LRootPane np = new LRootPane();
np.addChild(bg);
np.addChild(container);
np.addChild(back);
np.addChild(play);
setUI(np);
return true;
}
//@roseuid 4065D29D0073
/**
* This method will perform all of the necessary clean up operations
* once the object is no longer needed.
*
* @return boolean
*
*/
public boolean cleanUp() {
return true;
}
//@roseuid 4065D29D0091
/**
* This function essentially processes the action event that may
* have been thrown by the UI.
*
* @param ae ae
*
*
*/
public void actionPerformed(ActionEvent ae) {
String a = ae.getActionCommand();
if (a.equals("back")) {
//Go back to the main menu:
GameEngine.getInstance().setCurrentState(new MainMenuState());
} else if (a.equals("play")) {
//Play!
GameEngine.getInstance().startSingleLevel(container.getSelectedLevel());
}
/*
//The button has been clicked. Start the level:
//Transfer to game now:
GamePlayState gps = new GamePlayState("test_level");
GameEngine.getInstance().setCurrentState(gps);
*/
}
}

View File

@@ -0,0 +1,179 @@
package edu.gatech.cs2335.lemmings.engine;
import java.awt.Font;
import java.awt.Color;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.util.Random;
import edu.gatech.cs2335.lemmings.file.LevelReader;
import edu.gatech.cs2335.lemmings.gui.LIcon;
import edu.gatech.cs2335.lemmings.gui.LFancyLabel;
import edu.gatech.cs2335.lemmings.gui.LRootPane;
import edu.gatech.cs2335.lemmings.graphics.TileSetManager;
/**
* Class LoadLevelState: The display to show random humorous messages
* while the user is waiting for the level to load.
*
* <PRE>
* Revision History:
* v1.0 (Apr. 01, 2004) - Created the LoadLevelState class
* </PRE>
*
* @author <A HREF="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</A>
* @version Version 1.0, Apr. 01, 2004
*/
public class LoadLevelState extends AbstractGameState {
/**
* The level that we will be loading here.
*/
private Level level;
/**
* Number of millis we want to pass between the sayings.
*/
// private final long SAYING_DELAY = 4000;
/**
* List of things to say to the user.
*/
private final String[] sayings = {
"Drawing graffiti..",
"Circlin' da 'hood...",
"Intimidating nubs...",
"Chillin'...",
"Doing stuff...",
"Bling Blingin'...",
"You should be playin' Doom now...",
"Makin' Waves...",
"Writin' da JUnit tests...",
"Tracin' rays...",
"Studyin' Physics...",
"Renderin' Sprites...",
"Drawing pretty graphics...",
"Checkstylin'...",
"Floatin'...",
"Makin' final preparations...",
"Updatin' the repository...",
"Writing clever sayings...",
"Isn't it annoying to wait like this?",
"Blockin' unnecessary movement...",
"Givin' out the drills...",
"Assessing the llama population...",
};
/**
* The label to display our message to the user in.
*/
private LFancyLabel message;
/**
* Random number generator.
*/
private Random generator;
/**
* Creates a new <code>LoadLevelState</code> instance.
*/
public LoadLevelState() {
level = null;
generator = new Random(System.currentTimeMillis());
//Initialize background:
LIcon bg = new LIcon(TileSetManager.getInstance()
.getTileSet("bg_loading"));
bg.setShown(true);
bg.setPosition(new Point(0, 0));
//Initialize label:
message = new LFancyLabel();
message.setForeground(Color.black);
message.setFont(LFancyLabel.DEFAULT_FONT.deriveFont(Font.BOLD, 18.0f));
message.setText("");
message.setShown(true);
message.setPosition(new Point(300, 300));
//Initialize UI:
LRootPane np = new LRootPane();
np.addChild(bg);
np.addChild(message);
setUI(np);
}
/**
* This method will initialize the state that it belongs to. It will
* then return true upon success, and false upon failure.
*
* @return boolean
*/
public boolean initialize() {
updateText();
return true;
}
/**
* This method will perform all of the necessary clean up operations
* once the object is no longer needed.
*
* @return boolean
*
*/
public boolean cleanUp() {
level = null;
return true;
}
//@roseuid 4066242E016E
/**
* This function essentially processes the action event that may
* have been thrown by the UI.
*
* @param ae ae
*
*/
public void actionPerformed(ActionEvent ae) {
//The user can't click anything here, so...
}
/**
* Loads the level with the specified id.
*
* @param id a <code>String</code> value
*/
public synchronized void loadLevel(final String id) {
new Thread(new Runnable() {
public void run() {
level = LevelReader.getInstance().loadLevel(id);
levelLoaded();
}
}).start();
}
/**
* This function will be done when the level is done loading.
*/
private void levelLoaded() {
//Transfer control to Game Play State:
GameEngine.getInstance()
.setCurrentState(new GamePlayState(level));
}
/**
* Updates the text in the label.
*/
private void updateText() {
message.setText(sayings[generator.nextInt(sayings.length)]);
}
}

View File

@@ -0,0 +1,208 @@
package edu.gatech.cs2335.lemmings.engine;
import java.awt.Point;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import edu.gatech.cs2335.lemmings.gui.LIcon;
import edu.gatech.cs2335.lemmings.gui.LButton;
import edu.gatech.cs2335.lemmings.gui.LRootPane;
import edu.gatech.cs2335.lemmings.gui.LLeafComponent;
import edu.gatech.cs2335.lemmings.gui.LComponent;
import edu.gatech.cs2335.lemmings.gui.ITypable;
import edu.gatech.cs2335.lemmings.graphics.Looping;
import edu.gatech.cs2335.lemmings.graphics.Direction;
import edu.gatech.cs2335.lemmings.graphics.AnimatedSprite;
import edu.gatech.cs2335.lemmings.graphics.TileSetManager;
/**
* This is the main menu state. It displays the main menu stuff, which
* allows the player to select to play the single player game, the
* multiplayer game, or quit.
*
* @author <A HREF="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</A>
*/
public class MainMenuState extends AbstractGameState {
/**
* Creates a new <code>MainMenuState</code> instance.
*
*/
public MainMenuState() {
//Make sure that the resources we want are loaded:
TileSetManager.getInstance().getTileSet("bg_main");
TileSetManager.getInstance().getTileSet("mmb_single");
TileSetManager.getInstance().getTileSet("mmb_multi");
TileSetManager.getInstance().getTileSet("mmb_quit");
}
//@roseuid 4065D29D005F
/**
* This method will initialize the state that it belongs to. It will
* then return true upon success, and false upon failure.
*
* @return boolean
*
*/
public boolean initialize() {
//Initialize background:
LIcon bg = new LIcon(TileSetManager.getInstance().getTileSet("bg_main"));
bg.setShown(true);
bg.setPosition(new Point(0, 0));
//Initialize Buttons:
Point pos = new Point(63, 278);
LButton single = new LButton();
single.setPosition(new Point(pos));
single.setImage(new AnimatedSprite(TileSetManager.getInstance()
.getTileSet("mmb_single"),
Direction.NO_DIRECTION, Looping.NONE));
single.addActionListener(this);
single.setActionCommand("single");
single.setShown(true);
pos.x = 575;
pos.y = 292;
LButton multi = new LButton();
multi.setPosition(new Point(pos));
multi.setImage(new AnimatedSprite(TileSetManager.getInstance()
.getTileSet("mmb_multi"),
Direction.NO_DIRECTION, Looping.NONE));
multi.addActionListener(this);
multi.setActionCommand("multi");
multi.setShown(true);
pos.x = 315;
pos.y = 278;
LButton cred = new LButton();
cred.setPosition(new Point(pos));
cred.setImage(new AnimatedSprite(TileSetManager.getInstance()
.getTileSet("mmb_credits"),
Direction.NO_DIRECTION, Looping.NONE));
cred.addActionListener(this);
cred.setActionCommand("cred");
cred.setShown(true);
pos.x = 15;
pos.y = 530;
LButton help = new LButton();
help.setPosition(new Point(pos));
help.setImage(new AnimatedSprite(TileSetManager.getInstance()
.getTileSet("mmb_help"),
Direction.NO_DIRECTION, Looping.NONE));
help.addActionListener(this);
help.setActionCommand("help");
help.setShown(true);
pos.x = 690;
pos.y = 515;
LButton quit = new LButton();
quit.setPosition(new Point(pos));
quit.setImage(new AnimatedSprite(TileSetManager.getInstance()
.getTileSet("mmb_quit"),
Direction.NO_DIRECTION, Looping.NONE));
quit.addActionListener(this);
quit.setActionCommand("quit");
quit.setShown(true);
//Initialize UI:
LRootPane np = new LRootPane();
np.addChild(bg);
np.addChild(single);
np.addChild(multi);
np.addChild(cred);
np.addChild(help);
np.addChild(quit);
np.addChild(new LKeyListener() {
public void processKeyTyped(char key, int modifiers) {
if (key == 'a') {
GameEngine.getInstance()
.setCurrentState(new AttractState("Attract"));
}
}
});
setUI(np);
return true;
}
//@roseuid 4065D29D0073
/**
* This method will perform all of the necessary clean up operations
* once the object is no longer needed.
*
* @return boolean
*
*/
public boolean cleanUp() {
return true;
}
//@roseuid 4065D29D0091
/**
* This function essentially processes the action event that may
* have been thrown by the UI.
*
* @param ae ae
*
*
*/
public void actionPerformed(ActionEvent ae) {
String ac = ae.getActionCommand();
if (GameEngine.VERBOSE) {
System.out.println("MainMenuState: Button clicked - " + ac);
System.out.flush();
}
if ("single".equals(ac)) {
//Go to level selection:
GameEngine.getInstance().setCurrentState(new LevelSelectionState());
} else if ("multi".equals(ac)) {
//Go to multiplayer setup screen:
GameEngine.getInstance().setCurrentState(new MultiplayerSetupState());
} else if ("cred".equals(ac)) {
//Go to the credits screen:
GameEngine.getInstance().setCurrentState(new CreditsState());
} else if ("help".equals(ac)) {
GameEngine.getInstance().setCurrentState(new HelpState());
} else if ("quit".equals(ac)) {
System.exit(0);
}
}
/**
* Listens to keys and stuff.
*/
private abstract class LKeyListener
extends LLeafComponent implements ITypable {
/**
* Deep-copies self <b>into the component</b> passed in.
*
* @param component a <code>LComponent</code> value
*/
protected void copy(LComponent component) {
}
/**
* Performs all of the necessary drawing for this control only. The
* children will be taken care of separately. This method need not
* concern itself with them.
*
* @param g a <code>Graphics</code> value
* @return a <code>boolean</code> value
*/
protected boolean paint(Graphics g) {
return true;
}
}
}

View File

@@ -0,0 +1,473 @@
package edu.gatech.cs2335.lemmings.engine;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.Dimension;
import java.awt.image.BufferedImage;
//import java.awt.Rectangle;
import java.awt.AlphaComposite;
import edu.gatech.cs2335.lemmings.graphics.TileSet;
import edu.gatech.cs2335.lemmings.graphics.ImageLoader;
import edu.gatech.cs2335.lemmings.graphics.AnimatedSprite;
import edu.gatech.cs2335.lemmings.graphics.Direction;
import edu.gatech.cs2335.lemmings.graphics.Looping;
import edu.gatech.cs2335.lemmings.physics.PhysicsEngine;
/**
* The map on which stuff will be happening.
*
* @author <A HREF="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</A>
* @author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose Caban</A>
*/
public class Map {
/**
* The background image to display in this map.
*/
private BufferedImage background;
/**
* The texture image to use for the ground.
*/
private BufferedImage texture;
/**
* The unbreakable texture used for ground
*/
private BufferedImage unbreakableTexture;
/**
* This is the map itself. It is not technically a "map", but rather
* a color key for the map.
*/
private BufferedImage map;
/**
* Unbreakable map
*/
private BufferedImage unbreakableMap;
/**
* This is the actual displayed map
*/
private BufferedImage gameMap;
/**
* This is the indestructable game Map
*/
private BufferedImage indestructGameMap;
/**
* The water animation displayed on the map.
*/
private AnimatedSprite waterAnimation;
//////////////////
// Constructors //
//////////////////
/**
* Creates a new <code>Map</code> instance.
*
*/
public Map() {
background = null;
map = null;
}
///////////////////////////
// Accessors / Modifiers //
///////////////////////////
/**
* Access method for the background property.
*
* @return the current value of the background property
*/
public BufferedImage getBackground() {
return background;
}
/**
* Sets the value of the background property.
*
* @param aBackground the new value of the background property
*/
public void setBackground(BufferedImage aBackground) {
background = aBackground;
}
/**
* Access method for the texture property.
*
* @return the current value of the texture property
*/
public BufferedImage getTexture() {
return texture;
}
/**
* Sets the value of the texture property.
*
* @param aTexture the new value of the texture property
*/
public void setTexture(BufferedImage aTexture) {
texture = aTexture;
}
/**
* Method setUnbreakableTexture
*
*
* @param unbreakableTexture ub
*
*/
public void setUnbreakableTexture(BufferedImage unbreakableTexture) {
this.unbreakableTexture = unbreakableTexture;
}
/**
* Method getUnbreakableTexture
*
*
* @return BufferedImage
*
*/
public BufferedImage getUnbreakableTexture() {
return (this.unbreakableTexture);
}
/**
* Access method for the map property.
*
* @return the current value of the map property
*/
public BufferedImage getMap() {
return map;
}
/**
* Sets the value of the map property.
*
* @param aMap the new value of the map property
*/
public void setMap(BufferedImage aMap) {
map = aMap;
}
/**
* Describe <code>getGameMap</code> method here.
*
* @return a <code>BufferedImage</code> value
*/
public BufferedImage getGameMap() {
return (this.gameMap);
}
/**
* Access method for the size property.
*
* @return the current value of the size property
*/
public Dimension getSize() {
return new Dimension(map.getWidth(), map.getHeight());
}
/**
* Returns the water animation.
*
* @return an <code>AnimatedSprite</code> value
*/
public AnimatedSprite getWaterAnimation() {
return waterAnimation;
}
/**
* Describe <code>setWaterAnimation</code> method here.
*
* @param set a <code>TileSet</code> value
*
*/
public void setWaterAnimation(TileSet set) {
waterAnimation = new AnimatedSprite(set,
Direction.NO_DIRECTION,
Looping.INFINITE);
}
/////////////
// Methods //
/////////////
/**
* This will create a Game Map for use in drawing to screen.
* Parses the Mask and Texture File to spit out a map.
*
* @return the new gameMap to draw to screen.
*/
public BufferedImage createGameMap() {
//ensure that the map and textures are loaded
if (map == null || texture == null) {
return null;
}
//Set up variables
int mapWidth = map.getWidth() ,
mapHeight = map.getHeight() ,
texWidth = texture.getWidth() ,
texHeight = texture.getHeight();
int x, y, i, j, i2, j2; //x,y -> map, i,j -> texture
//initialize the game Map
this.gameMap =
ImageLoader.getInstance()
.createBlankImage(map.getWidth(), map.getHeight());
this.indestructGameMap = ImageLoader.getInstance()
.createBlankImage(map.getWidth(), map.getHeight());
this.unbreakableMap = ImageLoader.getInstance()
.createBlankImage(map.getWidth(), map.getHeight());
// Graphics2D g = gameMap.createGraphics();
//Go through the map and stick everything where its supposed to be
i = 0;
j = 0;
i2 = 0;
j2 = 0;
for (x = 0; x < mapWidth; x++) {
for (y = 0; y < mapHeight; y++) {
if (map.getRGB(x, y)
== MapSettings.getInstance().getUnbreakableColor()) {
gameMap.setRGB(x, y, unbreakableTexture.getRGB(i2, j2));
indestructGameMap.setRGB(x, y, unbreakableTexture.getRGB(i2, j2));
unbreakableMap.setRGB(x, y, MapSettings.getUnbreakableColor());
} else if (map.getRGB(x, y) != -16777216) {
gameMap.setRGB(x, y, texture.getRGB(i, j));
}
if (++j >= texHeight) {
j = 0;
}
if (++j2 >= unbreakableTexture.getHeight()) {
j2 = 0;
}
}
if (++i >= texWidth) {
i = 0;
}
if (++i2 >= unbreakableTexture.getWidth()) {
i2 = 0;
}
}
return gameMap;
}
//@roseuid 40660B3403D2
/**
* When someone creates something on the map, the thing will be
* added to the map. Use this method.
*
* @param shape The shape to add to the map.
* @param color The color of the shape
*
*/
public void addShape(Shape shape, Color color) {
Graphics2D g = (Graphics2D) PhysicsEngine.getInstance()
.getCurrentMap().getGraphics();
Graphics2D g2 = (Graphics2D) this.gameMap.getGraphics();
g.setColor(color);
g.fill(shape);
g2.setColor(color);
g2.fill(shape);
}
//@roseuid 40660B8C017F
/**
* When something explodes, digs, or mines, some part of the map can
* be destroyed. This is where this function is called. The shape
* passed in is what will be removed from the map. Note that only
* "diggable" elements will be removed. The undiggable ones will
* still persist.
*
* @param shape The shape to remove from the map.
*
*/
public void subtractShape(Shape shape) {
Graphics2D g = (Graphics2D) PhysicsEngine.getInstance()
.getCurrentMap().getGraphics();
Graphics2D g2 = (Graphics2D) this.gameMap.getGraphics();
g.setColor(Color.black);
g.fill(shape);
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.0f));
g2.fill(shape);
}
/**
* Create the GUI and show it. For thread safety,
* this method should be invoked from the
* event-dispatching thread.
*/
private static void createAndShowGUI() {
//Make sure we have nice window decorations.
//javax.swing.JFrame.setDefaultLookAndFeelDecorated(true);
//Create and set up the window.
final javax.swing.JFrame frame
= new javax.swing
.JFrame("Map Test",
java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment()
.getDefaultScreenDevice().getDefaultConfiguration());
frame.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
//Display the window.
frame.setSize(800, 600);
frame.setVisible(true);
//Initialize double buffering:
//frame.createBufferStrategy(2);
//Create and set up the content pane.
final Level l = edu.gatech.cs2335.lemmings.file.LevelReader.getInstance()
.loadLevel("test_level");
javax.swing.JPanel newContentPane
= new javax.swing.JPanel(new java.awt.BorderLayout());
//newContentPane.add(tst, java.awt.BorderLayout.CENTER);
newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);
//Initialize double buffering:
frame.createBufferStrategy(2);
final java.awt.image.BufferStrategy strategy = frame.getBufferStrategy();
new Thread(new Runnable() {
public void run() {
long lastFrame = System.currentTimeMillis();
BufferedImage im = l.getMap().createGameMap();
System.out.println("\n\n\n\n\n\n\n");
System.out.println("Image: \n" + im);
System.out.println("\n\n\n\n\n\n\n");
System.out.flush();
while (true) {
int width = frame.getWidth();
int height = frame.getHeight();
//Get the graphics context from buffer strategy:
java.awt.Graphics2D g =
(java.awt.Graphics2D) strategy.getDrawGraphics();
//Do the drawing:
g.setColor(java.awt.Color.gray);
g.fillRect(0, 0, width, height);
width /= 2;
height /= 2;
g.drawImage(im, null, 0, 0);
//Flip buffer:
strategy.show();
//Cap the frame rate:
lastFrame += 20; //Frame rate
try {
Thread.sleep(Math.max(0,
lastFrame - System.currentTimeMillis()));
} catch (Exception e) {
continue;
}
}
}
}
).start();
}
/**
* Main
* @param args args
*/
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}

View File

@@ -0,0 +1,75 @@
package edu.gatech.cs2335.lemmings.engine;
import java.awt.Color;
/**
* Map Settings, thanks to PMD, a Singleton class
*
* Holds Physics Constants
*
* @author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose Caban</A>
*/
public class MapSettings {
/**
* The unbreakable color
*/
private static final int UNBREAKABLECOLOR = -8421505;
/**
* The passable color
*/
private static final int PASSABLECOLOR = -16777216;
/**
* TRANSPARENT Color
*/
public static final Color TRANSPARENT = new Color(255, 255, 255, 100);
/**
* The Singleton Map Settings
*/
private static MapSettings instance = new MapSettings();
/**
* Creates a new <code>MapSettings</code> instance.
*
*/
private MapSettings() { }
/**
* Method getUnbreakableColor
*
*
* @return int
*
*/
public static int getUnbreakableColor() {
return (MapSettings.UNBREAKABLECOLOR);
}
/**
* Method getPassableColor
*
*
* @return int
*
*/
public static int getPassableColor() {
return (MapSettings.PASSABLECOLOR);
}
/**
* Method getInstance
*
*
* @return mapsettings
*
*/
public static MapSettings getInstance() {
return (MapSettings.instance);
}
}

View File

@@ -0,0 +1,227 @@
package edu.gatech.cs2335.lemmings.engine;
import java.awt.Font;
import java.awt.Color;
import java.awt.Point;
import java.awt.event.ActionEvent;
//import java.util.Random;
import edu.gatech.cs2335.lemmings.file.LevelReader;
//import edu.gatech.cs2335.lemmings.gui.LIcon;
//import edu.gatech.cs2335.lemmings.gui.LButton;
import edu.gatech.cs2335.lemmings.gui.LLabel;
import edu.gatech.cs2335.lemmings.gui.LFancyLabel;
import edu.gatech.cs2335.lemmings.gui.LRootPane;
//import edu.gatech.cs2335.lemmings.graphics.Looping;
//import edu.gatech.cs2335.lemmings.graphics.Direction;
//import edu.gatech.cs2335.lemmings.graphics.AnimatedSprite;
//import edu.gatech.cs2335.lemmings.graphics.TileSetManager;
/**
* Class MultiLevelResultsState: this is the multilevel result state.
*
* <PRE>
* Revision History:
* v1.0 (Apr. 16, 2004) - Created the MultiLevelResultsState class
* </PRE>
*
* @author <A HREF="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</A>
* @version Version 1.0, Apr. 16, 2004
*/
public final class MultiLevelResultsState extends LevelResultsState {
/**
* Describe variable <code>numCarryOver</code> here.
*
*/
private int numCarryOver;
/**
* Describe variable <code>otherCarryOver</code> here.
*
*/
private int otherCarryOver;
/**
*
*/
private LLabel lblCarryOver;
/**
*
*/
private int n;
/**
* Describe variable <code>lblOtherPlayer</code> here.
*
*/
private LLabel lblOtherPlayer;
/**
*
*/
private AbstractGameState target;
/**
* Creates a new <code>MultiLevelResultsState</code> instance.
*@param l l
*@param num num
*@param otherNum on
*/
public MultiLevelResultsState(Level l, int num, int otherNum) {
super(l);
setNumCarryOver(num);
setOtherCarryOver(otherNum);
}
/**
* This method will initialize the state that it belongs to. It will
* then return true upon success, and false upon failure.
*
* @return boolean
*/
public boolean initialize() {
super.initialize();
lblCarryOver = new LLabel();
lblCarryOver
.setText("Your Carry Over Lemmings: " + numCarryOver);
lblCarryOver.setPosition(new Point(300, 280));
lblCarryOver.setShown(true);
lblOtherPlayer = new LLabel();
lblOtherPlayer
.setText("Your Opponent's Carry Over Lemmings: " + otherCarryOver);
lblOtherPlayer.setPosition(new Point(300, 300));
lblOtherPlayer.setShown(true);
LRootPane u = getUI();
u.addChild(lblCarryOver);
u.addChild(lblOtherPlayer);
if (numCarryOver < 1) {
LFancyLabel resultLabel = new LFancyLabel();
resultLabel.setForeground(Color.red);
resultLabel.setFont(LFancyLabel.DEFAULT_FONT.deriveFont(Font.BOLD,
20.0f));
resultLabel.setText("You Lose!");
resultLabel.setPosition(new Point(300, 400));
resultLabel.setShown(true);
u.addChild(resultLabel);
target = new MainMenuState();
} else if (otherCarryOver < 1) {
LFancyLabel resultLabel = new LFancyLabel();
resultLabel.setForeground(Color.red);
resultLabel.setFont(LFancyLabel.DEFAULT_FONT.deriveFont(Font.BOLD,
20.0f));
resultLabel.setText("You Win!");
resultLabel.setPosition(new Point(300, 400));
resultLabel.setShown(true);
target = new MainMenuState();
u.addChild(resultLabel);
}
//The player saved enough lemmings.
String name = getLevel().getData().getId();
String[] levels = LevelReader.getInstance().getLevelList();
boolean found = false;
n = 0;
for (int i = 0; i < levels.length; i++) {
if (name.equals(levels[i])) {
if (i == levels.length - 1) {
LFancyLabel resultLabel = new LFancyLabel();
resultLabel.setForeground(Color.red);
resultLabel.setFont(LFancyLabel.DEFAULT_FONT.deriveFont(Font.BOLD,
20.0f));
resultLabel.setPosition(new Point(300, 400));
resultLabel.setShown(true);
if (numCarryOver > otherCarryOver) {
resultLabel.setText("You Win!");
} else if (numCarryOver < otherCarryOver) {
resultLabel.setText("You Lose!");
} else {
resultLabel.setText("It's a Tie...");
}
target = new MainMenuState();
u.addChild(resultLabel);
} else {
n = i + 1;
found = true;
break;
}
}
}
return true;
}
/**
* Get the value of otherCarryOver.
* @return value of otherCarryOver.
*/
public int getOtherCarryOver() {
return otherCarryOver;
}
/**
* Set the value of otherCarryOver.
* @param v Value to assign to otherCarryOver.
*/
public void setOtherCarryOver(int v) {
this.otherCarryOver = v;
}
/**
* Get the value of numCarryOver.
* @return value of numCarryOver.
*/
public int getNumCarryOver() {
return numCarryOver;
}
/**
* Set the value of numCarryOver.
* @param v Value to assign to numCarryOver.
*/
public void setNumCarryOver(int v) {
this.numCarryOver = v;
}
/**
* This function essentially processes the action event that may
* have been thrown by the UI.
*
* @param ae ae
*
*/
public void actionPerformed(ActionEvent ae) {
String a = ae.getActionCommand();
if (a.equals("back")) {
//Go back to the main menu:
GameEngine.getInstance().setCurrentState(new MainMenuState());
} else if (a.equals("play")) {
if (target != null) {
GameEngine.getInstance().setCurrentState(target);
} else {
//Go to the next level:
GameEngine.getInstance().startMultiLevel(n, numCarryOver);
}
}
}
}

View File

@@ -0,0 +1,397 @@
package edu.gatech.cs2335.lemmings.engine;
import edu.gatech.cs2335.lemmings.networking.PauseMessage;
import edu.gatech.cs2335.lemmings.networking.UpdateMessage;
import edu.gatech.cs2335.lemmings.networking.ChangeSpeedMessage;
import edu.gatech.cs2335.lemmings.networking.NukeRequestMessage;
import edu.gatech.cs2335.lemmings.networking.ChangeLemmingFlowMessage;
import edu.gatech.cs2335.lemmings.networking.IdentificationMessage;
import edu.gatech.cs2335.lemmings.networking.LemmingNetworking;
import edu.gatech.cs2335.lemmings.networking.MessageFactory;
import edu.gatech.cs2335.lemmings.networking.AbstractMessage;
import edu.gatech.cs2335.lemmings.networking.StatsMessage;
import edu.gatech.cs2335.lemmings.networking.LevelFinishMessage;
import java.awt.Font;
import java.awt.Color;
import java.awt.Point;
//import java.awt.Rectangle;
//import java.awt.event.ActionEvent;
//import java.awt.Point;
//import java.awt.Color;
//import java.awt.Rectangle;
//import java.awt.Graphics;
//import java.awt.Dimension;
//import java.awt.event.ActionEvent;
//import java.awt.event.ActionListener;
import java.util.List;
import java.util.Vector;
//import edu.gatech.cs2335.lemmings.engine.lemmingjob.LemmingJobSettings;
//import edu.gatech.cs2335.lemmings.graphics.Looping;
//import edu.gatech.cs2335.lemmings.graphics.Direction;
//import edu.gatech.cs2335.lemmings.graphics.AnimatedSprite;
//import edu.gatech.cs2335.lemmings.graphics.TileSetManager;
//import edu.gatech.cs2335.lemmings.gui.ITypable;
//import edu.gatech.cs2335.lemmings.gui.LLeafComponent;
//import edu.gatech.cs2335.lemmings.gui.LComponent;
//import edu.gatech.cs2335.lemmings.gui.JobContainer;
import edu.gatech.cs2335.lemmings.gui.LRootPane;
//import edu.gatech.cs2335.lemmings.gui.LButton;
//import edu.gatech.cs2335.lemmings.gui.LToggleButton;
import edu.gatech.cs2335.lemmings.gui.LFancyLabel;
//import edu.gatech.cs2335.lemmings.gui.GamePlayPanel;
//import edu.gatech.cs2335.lemmings.graphics.Renderer;
//import edu.gatech.cs2335.lemmings.physics.PhysicsEngine;
//import edu.gatech.cs2335.lemmings.file.LevelReader;
//import edu.gatech.cs2335.lemmings.networking.LemmingNetworking;
import edu.gatech.cs2335.lemmings.networking.MessageSettings;
//import edu.gatech.cs2335.lemmings.networking.MessageFactory;
//import edu.gatech.cs2335.lemmings.networking.AbstractMessage;
//import java.util.Vector;
//import java.util.List;
/**
* The mutiplayer game state, where the actual game is displayed and played.
*
* Koala Update - fixed
*
* @author <A href="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</A>
* @version 1.0
*/
public class MultiplayerGameplayState extends GamePlayState {
/**
* bDebug is for turning debugging output on and off
*/
//private final boolean bDebug = false;
/**
* Boolean for VERBOSE output
*/
private static final boolean VERBOSE = true;
/**
* True if other player has requested a NUKE
*/
private boolean otherPlayerRequestedNuke = false;
/**
* True if this player has requested a NUKE
*/
private boolean playerRequestedNuke = false;
/**
* Holds the Level information for the other player
*/
private Level otherPlayerLevel;
/**
* The label showing the number of lemmings released.
*/
private LFancyLabel releasedLabel;
/**
* The label that will show how many lemmings have been saved.
*/
private LFancyLabel savedLabel;
/**
* This label will show the number of lemmings out in the field.
*/
private LFancyLabel outLabel;
/**
*dead
*/
private int deadLemmings;
/**
*saved
*/
private int savedLemmings;
/**
*released
*/
private int releasedLemmings;
/**
*total
*/
private int totalLemmings;
/**
* Has one player done the thing?
*/
private boolean flag;
/**
* constructor
*@param l level
*
*/
public MultiplayerGameplayState (Level l) {
super(l);
this.otherPlayerLevel = l.duplicate();
}
/**
* Describe <code>specialInitialize</code> method here.
*
*/
protected synchronized void specialInitialize() {
releasedLabel = new LFancyLabel();
releasedLabel.setForeground(Color.green);
releasedLabel
.setFont(LFancyLabel.DEFAULT_FONT.deriveFont(Font.BOLD, 20.0f));
releasedLabel.setText("");
releasedLabel.setPosition(new Point(600, 50));
releasedLabel.setShown(true);
savedLabel = new LFancyLabel();
savedLabel.setForeground(Color.green);
savedLabel.setFont(LFancyLabel.DEFAULT_FONT.deriveFont(Font.BOLD, 20.0f));
savedLabel.setText("");
savedLabel.setPosition(new Point(600, 70));
savedLabel.setShown(true);
outLabel = new LFancyLabel();
outLabel.setForeground(Color.green);
outLabel.setFont(LFancyLabel.DEFAULT_FONT.deriveFont(Font.BOLD, 20.0f));
outLabel.setText("");
outLabel.setPosition(new Point(600, 90));
outLabel.setShown(true);
LRootPane u = getUI();
u.addChild(releasedLabel);
u.addChild(savedLabel);
u.addChild(outLabel);
}
/**
* Whatever else needs to be done for pause.
*/
protected void specialPauseHandle() {
List data = new Vector();
data.add("MrPause");
data.add(Boolean.valueOf(isPauseSelected()));
AbstractMessage am = MessageFactory.getInstance().
createMessage(MessageSettings.TYPE_PAUSE, data);
LemmingNetworking.getInstance().sendMessage(am);
}
/**
* Whatever else needs to be done for speedup.
*/
protected void specialSpeedupHandle() {
List data = new Vector();
data.add("MrSpeed");
data.add(new Integer(getGameSpeed()));
AbstractMessage am = MessageFactory.getInstance().
createMessage(MessageSettings.TYPE_SPEED, data);
LemmingNetworking.getInstance().sendMessage(am);
}
/**
* Whatever else needs to be done for nuke.
*/
protected void specialNukeHandle() {
requestNuke();
}
/**
* Whatever else needs to be done for increase.
*/
protected void specialIncreaseHandle() {
List data = new Vector();
data.add("MrRate");
data.add(new Integer(getLemmingFlow()));
AbstractMessage am = MessageFactory.getInstance().
createMessage(MessageSettings.TYPE_FLOW, data);
LemmingNetworking.getInstance().sendMessage(am);
}
/**
* Whatever else needs to be done for decrease.
*/
protected void specialDecreaseHandle() {
List data = new Vector();
data.add("MrRate");
data.add(new Integer(getLemmingFlow()));
AbstractMessage am = MessageFactory.getInstance().
createMessage(MessageSettings.TYPE_FLOW, data);
LemmingNetworking.getInstance().sendMessage(am);
}
/**
* Describe <code>specialUpdate</code> method here.
*
*/
protected void specialUpdate() {
releasedLabel.setText("Released: "
+ Integer.toString(releasedLemmings)
+ "/" + Integer.toString(totalLemmings));
savedLabel.setText("Saved: "
+ Integer.toString(savedLemmings));
outLabel.setText("Out: "
+ Integer.toString(deadLemmings));
}
/**
* Updates both players levels based on msg data
* @param msg , network message holding game state updates
*/
public void receiveMessage(AbstractMessage msg) {
if (msg instanceof StatsMessage) {
deadLemmings = ((StatsMessage) msg).getLemmingsDead();
savedLemmings = ((StatsMessage) msg).getLemmingsSaved();
releasedLemmings = ((StatsMessage) msg).getLemmingsReleased();
totalLemmings = ((StatsMessage) msg).getLemmingsTotal();
} else if (msg instanceof NukeRequestMessage) {
//Seeing if we have to nuke and nuking if so
otherPlayerRequestedNuke = true;
if (playerRequestedNuke) {
//Send Nuke Message
List data = new Vector();
data.add(new String("NukeMessage"));
//Nuke them all
getLevel().nukeEmALL();
}
} else if (msg instanceof LevelFinishMessage) {
otherPlayerEnded();
} else if (msg instanceof UpdateMessage) {
getOtherPlayerLevel().updateLevel(msg);
} else if (msg instanceof PauseMessage) {
getPauseButton().setSelected(((PauseMessage) msg).getPause());
singlePauseButtonHandle();
if (((PauseMessage) msg).getPause()) {
getOtherPlayerLevel().pause();
} else {
getOtherPlayerLevel().unpause();
}
} else if (msg instanceof ChangeLemmingFlowMessage) {
this.getOtherPlayerLevel().setLemmingFlow(
((ChangeLemmingFlowMessage) msg).getLemmingFlow());
} else if (msg instanceof ChangeSpeedMessage) {
//Do we really want the other player controlling speed?
// this.setGameSpeed(((ChangeSpeedMessage) msg).getSpeed());
int stuff = 0;
stuff++;
} else if (msg instanceof IdentificationMessage) {
if (VERBOSE) {
System.out.println("IdentificationMessage received during play");
}
} else {
//This would be bad
System.err.println("MultiplayerGameplayState:receiveMessage: "
+ "Msg was not correct type");
}
}
/**
* Ends the level and goes on to the next state.
*/
public synchronized void endLevel() {
//Go to the level results state:
getLevel().pause();
//Send out the endmessage
AbstractMessage am = MessageFactory.getInstance()
.makeBlankMessage(MessageSettings.TYPE_LEVELEND, "nUb");
LemmingNetworking.getInstance().sendMessage(am);
if (flag) {
int lemmingsSaved = getLevel().getLemmingsSaved();
GameEngine.getInstance()
.setCurrentState(new
MultiLevelResultsState(getLevel(),
lemmingsSaved, //My lemmings
savedLemmings)); //Opponent's
//lemmings
} else {
flag = true;
}
}
/**
* Konchil on.
*/
public synchronized void otherPlayerEnded() {
if (flag) {
int lemmingsSaved = getLevel().getLemmingsSaved();
GameEngine.getInstance()
.setCurrentState(new
MultiLevelResultsState(getLevel(),
lemmingsSaved, //My lemmings
savedLemmings)); //Opponent's
//lemmings
} else {
flag = true;
}
}
/**
* Accessor for otherPlayerlevel
* @return Level , Level of remote player
*/
public Level getOtherPlayerLevel() {
return otherPlayerLevel;
}
/**
* Determines if the little guys should be nuked and nukes.
*/
public void requestNuke() {
playerRequestedNuke = true;
List data = new Vector();
data.add(new String("NukeMessage"));
AbstractMessage nukem =
MessageFactory.getInstance().createMessage("NUKE", data);
LemmingNetworking.getInstance().sendMessage(nukem);
if (otherPlayerRequestedNuke) {
//Nuke them all
getLevel().nukeEmALL();
getOtherPlayerLevel().nukeEmALL();
}
}
}

View File

@@ -0,0 +1,204 @@
package edu.gatech.cs2335.lemmings.engine;
import java.awt.Point;
import java.awt.event.ActionEvent;
import edu.gatech.cs2335.lemmings.gui.LIcon;
import edu.gatech.cs2335.lemmings.gui.LLabel;
import edu.gatech.cs2335.lemmings.gui.LButton;
import edu.gatech.cs2335.lemmings.gui.LRootPane;
import edu.gatech.cs2335.lemmings.gui.LTextField;
import edu.gatech.cs2335.lemmings.graphics.Looping;
import edu.gatech.cs2335.lemmings.graphics.Direction;
import edu.gatech.cs2335.lemmings.graphics.AnimatedSprite;
import edu.gatech.cs2335.lemmings.graphics.TileSetManager;
//import edu.gatech.cs2335.lemmings.networking.LemmingNetworking;
//import edu.gatech.cs2335.lemmings.file.LevelReader;
/**
* Class MultiplayerSetupState: This is where the player can either
* start up the server, or join an existing game.
*
* <PRE>
* Revision History:
* v1.0 (Apr. 14, 2004) - Created the MultiplayerSetupState class
* </PRE>
*
* @author <A HREF="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</A>
* @version Version 1.0, Apr. 14, 2004
*/
public class MultiplayerSetupState extends AbstractGameState {
/**
* The text field that will contain the IP of the host to connect to.
*/
private LTextField ipField;
/**
* Port.
*/
private LTextField portField;
/**
* Creates a new <code>MultiplayerSetupState</code> instance.
*/
public MultiplayerSetupState() {
}
/**
* This method will initialize the state that it belongs to. It will
* then return true upon success, and false upon failure.
*
* @return boolean
*
*/
public boolean initialize() {
//Initialize background:
LIcon bg = new LIcon(TileSetManager.getInstance().getTileSet("bg_mp"));
bg.setShown(true);
bg.setPosition(new Point(0, 0));
//Initialize labels:
LLabel lblHost = new LLabel();
lblHost.setText("Host: ");
lblHost.setShown(true);
lblHost.setPosition(new Point(300, 150));
LLabel lblPort = new LLabel();
lblPort.setText("Port: ");
lblPort.setShown(true);
lblPort.setPosition(new Point(300, 200));
ipField = new LTextField("localhost");
ipField.setShown(true);
ipField.setPosition(new Point(350, 150));
ipField.end();
portField = new LTextField("3333");
portField.setShown(true);
portField.setPosition(new Point(350, 200));
portField.end();
//Initialize Buttons:
LButton back = new LButton();
back
.setImage(new AnimatedSprite(TileSetManager.getInstance()
.getTileSet("mpb_back"),
Direction.NO_DIRECTION,
Looping.NONE));
back.setPosition(new Point(10, 590));
back.setShown(true);
back.setActionCommand("back");
back.addActionListener(this);
LButton host = new LButton();
host
.setImage(new AnimatedSprite(TileSetManager.getInstance()
.getTileSet("mpb_host"),
Direction.NO_DIRECTION,
Looping.NONE));
host.setPosition(new Point(345, 590));
host.setShown(true);
host.setActionCommand("host");
host.addActionListener(this);
LButton connect = new LButton();
connect
.setImage(new AnimatedSprite(TileSetManager.getInstance()
.getTileSet("mpb_connect"),
Direction.NO_DIRECTION,
Looping.NONE));
connect.setPosition(new Point(680, 590));
connect.setShown(true);
connect.setActionCommand("connect");
connect.addActionListener(this);
//Initialize UI:
LRootPane np = new LRootPane();
np.addChild(bg);
np.addChild(lblHost);
np.addChild(lblPort);
np.addChild(back);
np.addChild(host);
np.addChild(connect);
np.addChild(portField);
np.addChild(ipField);
setUI(np);
return true;
}
/**
* This method will perform all of the necessary clean up operations
* once the object is no longer needed.
*
* @return boolean
*
*/
public boolean cleanUp() {
return true;
}
/**
* Describe <code>getHost</code> method here.
*
* @return a <code>String</code> value
*/
private String getHost() {
return ipField.getText();
}
/**
* Describe <code>getPort</code> method here.
*
* @return an <code>int</code> value
*/
private int getPort() {
try {
return Integer.parseInt(portField.getText());
} catch (NumberFormatException nfe) {
return 3333;
}
}
/**
* This function essentially processes the action event that may
* have been thrown by the UI.
*
* @param ae ae
*
*
*/
public void actionPerformed(ActionEvent ae) {
String a = ae.getActionCommand();
if ("back".equals(a)) {
GameEngine.getInstance().setCurrentState(new MainMenuState());
} else if ("host".equals(a)) {
//Host an mp game:
int port = getPort();
GameEngine.getInstance().startMultiGame();
GameEngine.getInstance().getEcs().host(port);
} else if ("connect".equals(a)) {
//Connect to an existing game:
String host = getHost();
int port = getPort();
GameEngine.getInstance().startMultiGame();
GameEngine.getInstance().getEcs().connectTo(host, port);
}
}
}

View File

@@ -0,0 +1,175 @@
package edu.gatech.cs2335.lemmings.engine;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.Point;
import java.awt.Color;
//import java.awt.Rectangle;
//import java.awt.Graphics;
//import edu.gatech.cs2335.lemmings.engine.lemmingjob.LemmingJobSettings;
import edu.gatech.cs2335.lemmings.graphics.Looping;
import edu.gatech.cs2335.lemmings.graphics.Direction;
import edu.gatech.cs2335.lemmings.graphics.AnimatedSprite;
import edu.gatech.cs2335.lemmings.graphics.TileSetManager;
//import edu.gatech.cs2335.lemmings.gui.ITypable;
//import edu.gatech.cs2335.lemmings.gui.LLeafComponent;
//import edu.gatech.cs2335.lemmings.gui.LComponent;
//import edu.gatech.cs2335.lemmings.gui.JobContainer;
import edu.gatech.cs2335.lemmings.gui.LRootPane;
import edu.gatech.cs2335.lemmings.gui.LButton;
//import edu.gatech.cs2335.lemmings.gui.LToggleButton;
import edu.gatech.cs2335.lemmings.gui.LFancyLabel;
//import edu.gatech.cs2335.lemmings.gui.GamePlayPanel;
//import edu.gatech.cs2335.lemmings.graphics.Renderer;
//import edu.gatech.cs2335.lemmings.physics.PhysicsEngine;
//import edu.gatech.cs2335.lemmings.file.LevelReader;
//import java.awt.Point;
//import java.awt.event.ActionEvent;
import edu.gatech.cs2335.lemmings.gui.LIcon;
//import edu.gatech.cs2335.lemmings.gui.LButton;
//import edu.gatech.cs2335.lemmings.gui.LRootPane;
//import edu.gatech.cs2335.lemmings.graphics.Looping;
//import edu.gatech.cs2335.lemmings.graphics.Direction;
//import edu.gatech.cs2335.lemmings.graphics.AnimatedSprite;
//import edu.gatech.cs2335.lemmings.graphics.TileSetManager;
/**
* Class NetworkErrorState: Displays a network error...
*
* <PRE>
* Revision History:
* v1.0 (Apr. 21, 2004) - Created the NetworkErrorState class
* </PRE>
*
* @author <A HREF="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</A>
* @version Version 1.0, Apr. 21, 2004
*/
public class NetworkErrorState extends AbstractGameState {
/**
* Display debug information?
*/
public static final boolean VERBOSE = false;
/**
* The label to display our message to the user in.
*/
private LFancyLabel message;
/**
* Creates a new <code>NetworkErrorState</code> instance.
*/
public NetworkErrorState() {
//Initialize background:
LIcon bg = new LIcon(TileSetManager.getInstance()
.getTileSet("bg_ne"));
bg.setShown(true);
bg.setPosition(new Point(0, 0));
//Initialize label:
message = new LFancyLabel();
message.setForeground(Color.black);
message.setFont(LFancyLabel.DEFAULT_FONT.deriveFont(Font.BOLD, 18.0f));
message.setText("");
message.setShown(true);
message.setPosition(new Point(300, 300));
//Initialize button:
LButton goOn = new LButton();
goOn.setPosition(new Point(10, 590));
goOn.setImage(new AnimatedSprite(TileSetManager.getInstance()
.getTileSet("mpb_back"),
Direction.NO_DIRECTION, Looping.NONE));
goOn.addActionListener(this);
goOn.setActionCommand("goOn");
goOn.setShown(true);
//Initialize UI:
LRootPane np = new LRootPane();
np.addChild(bg);
np.addChild(message);
np.addChild(goOn);
setUI(np);
}
/**
* This method will initialize the state that it belongs to. It will
* then return true upon success, and false upon failure.
*
* @return boolean
*/
public boolean initialize() {
if (VERBOSE) {
System.err.println("NetworkErrorState: I am initialized!");
System.err.flush();
}
return true;
}
/**
* This method will perform all of the necessary clean up operations
* once the object is no longer needed.
*
* @return boolean
*
*/
public boolean cleanUp() {
setErrorMessage("");
if (VERBOSE) {
System.err.println("NetworkErrorState: I am cleaned up!");
System.err.flush();
}
return true;
}
/**
* Sets up the error message.
*
* @param msg a <code>String</code> value
*/
public void setErrorMessage(String msg) {
message.setText(new String(msg));
}
/**
* This function essentially processes the action event that may
* have been thrown by the UI.
*
* @param ae ae
*
*/
public void actionPerformed(ActionEvent ae) {
if (VERBOSE) {
System.err.println("NetworkErrorState: Got some action - "
+ ae.getActionCommand());
System.err.flush();
}
//Go back to the Multiplayer setup state:
GameEngine.getInstance().setCurrentState(new MultiplayerSetupState());
}
}

View File

@@ -0,0 +1,40 @@
package edu.gatech.cs2335.lemmings.engine;
/**
* Class Particle: When a lemming blows up, he makes particles. Well,
* here they are. :)
*
* Description from Jose:
* The particle class, used for ! particle effects !
*
* Nothing special to do here, the Physics Engine will handle the
* actual effects. The single function is used to test whether or
* not the particle should be killed.
*
* <PRE>
* Revision History:
* v2.0 (2004 - 4 - 20) - Made abstract
* v1.0 (Apr. 11, 2004) - Created the Particle class
* </PRE>
*
* @author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose Caban</A>
* @version Version 1.0, Apr. 11, 2004
*/
public abstract class Particle extends PrettySprite {
/**
* Creates a new <code>Particle</code> instance.
*@param s s
*/
public Particle(String s) {
super(s);
}
/**
* Should return true when the sprite is ready to kill self.
*
* @return a <code>boolean</code> value
*/
protected abstract boolean canKillSelf();
}

View File

@@ -0,0 +1,144 @@
package edu.gatech.cs2335.lemmings.engine;
//import java.awt.Dimension;
import java.awt.Rectangle;
import edu.gatech.cs2335.lemmings.graphics.TileSet;
import edu.gatech.cs2335.lemmings.graphics.Looping;
import edu.gatech.cs2335.lemmings.graphics.Direction;
import edu.gatech.cs2335.lemmings.graphics.AnimatedSprite;
import edu.gatech.cs2335.lemmings.graphics.TileSetManager;
import edu.gatech.cs2335.lemmings.physics.PhysicsObject;
/**
* Class Portal: Represents a portal in the map. It can be either an
* entrance, an exit, or a portal from one part of the map to another.
*
* <PRE>
* Revision History:
* v1.0 (Mar. 28, 2004) - Created the Portal class
* </PRE>
*
* @author <A HREF="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</A>
* @version Version 1.0, Mar. 28, 2004
*/
public abstract class Portal implements ICleanable {
/**
* The physics object associated with the portal.
*/
private PhysicsObject physics;
/**
* The animation associated with the portal.
*/
private AnimatedSprite animation;
/**
* The level that the portal is associated with.
*/
private Level parent;
/**
* The extent of the portal. If the lemming is within the
* rectangle, then it will be processed.
*/
private Rectangle extent;
/**
* Creates a new <code>Portal</code> instance.
*
* @param anim The name of the animation tileset to use.
*/
public Portal(String anim) {
//Set up physics:
physics = new PhysicsObject();
animation = new AnimatedSprite(TileSetManager.getInstance()
.getTileSet(anim),
Direction.NO_DIRECTION,
Looping.INFINITE);
setAnimation(anim); //Hack... Setting animation twice?? :/
parent = null;
}
/**
* Cleans up all references for the garbage collector.
*/
public void cleanUp() {
parent = null;
}
/**
* Returns the animation for this portal.
*
* @return an <code>AnimatedSprite</code> value
*/
public AnimatedSprite getAnimation() {
return animation;
}
/**
* Sets the animation with the specified name.
*
* @param name a <code>String</code> value
*/
protected final synchronized void setAnimation(String name) {
TileSet set = TileSetManager.getInstance().getTileSet(name);
Rectangle rect = set.getExtent(0);
setExtent(new Rectangle(rect));
animation.setAnimation(set);
}
/**
* Returns the physics object associated with this portal.
*
* @return a <code>PhysicsObject</code> value
*/
public PhysicsObject getPhysics() {
return physics;
}
/**
* Returns the physics object associated with this portal.
*
* @return a <code>PhysicsObject</code> value
*/
public Rectangle getExtent() {
return extent;
}
/**
* Returns the physics object associated with this portal.
*
* @param ext a <code>PhysicsObject</code> value
*/
public final synchronized void setExtent(Rectangle ext) {
extent = ext;
}
/**
* Returns the physics object associated with this portal.
*
* @return a <code>PhysicsObject</code> value
*/
public Level getParent() {
return parent;
}
/**
* Returns the physics object associated with this portal.
*
* @param l a <code>PhysicsObject</code> value
*/
public void setParent(Level l) {
parent = l;
}
/**
* This function will be called when a lemming enters this portal.
*
* @param l a <code>Lemming</code> value
*/
public abstract void processLemmingEntry(Lemming l);
}

View File

@@ -0,0 +1,102 @@
package edu.gatech.cs2335.lemmings.engine;
import java.util.StringTokenizer;
/**
* Class PortalFactory: Creates different portals.
*
* <PRE>
* Revision History:
* v1.0 (Apr. 22, 2004) - Created the PortalFactory class
* </PRE>
*
* @author <A HREF="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</A>
* @version Version 1.0, Apr. 22, 2004
*/
public class PortalFactory {
/**
* All the different kinds of portals.
*/
public static final String[] PORTAL_TYPES = {
"entrance",
"exit",
"fling_trap"
};
/**
* Describe constant <code>INSTANCE</code> here.
*
*/
private static final PortalFactory INSTANCE = new PortalFactory();
/**
* Creates a new <code>PortalFactory</code> INSTANCE.
*/
private PortalFactory() {
}
/**
* Describe <code>getInstance</code> method here.
*
* @return a <code>PortalFactory</code> value
*/
public static PortalFactory getInstance() {
return INSTANCE;
}
/**
* Describe <code>makePortal</code> method here.
*@param type type
*@param value value
* @return a <code>Portal</code> value
*/
public Portal makePortal(String type, String value) {
//Try to parse the coordinates out of the value first:
StringTokenizer st = new StringTokenizer(value);
int x;
int y;
if (!st.hasMoreTokens()) {
return null;
}
try {
x = Integer.parseInt(st.nextToken());
} catch (NumberFormatException nfe) {
return null;
}
if (!st.hasMoreTokens()) {
return null;
}
try {
y = Integer.parseInt(st.nextToken());
} catch (NumberFormatException nfe) {
return null;
}
//Got coordinates of the portal:
Portal result = null;
if (PORTAL_TYPES[0].equals(type)) {
result = new LevelEntrance();
} else if (PORTAL_TYPES[1].equals(type)) {
result = new LevelExit();
} else if (PORTAL_TYPES[2].equals(type)) {
result = new FlingTrap();
}
if (result == null) {
return null;
}
result.getPhysics().getPosition().setX(x);
result.getPhysics().getPosition().setY(y);
return result;
}
}

View File

@@ -0,0 +1,125 @@
package edu.gatech.cs2335.lemmings.engine;
import edu.gatech.cs2335.lemmings.graphics.Looping;
import edu.gatech.cs2335.lemmings.graphics.Direction;
import edu.gatech.cs2335.lemmings.graphics.TileSetManager;
import edu.gatech.cs2335.lemmings.graphics.AnimatedSprite;
import edu.gatech.cs2335.lemmings.physics.PhysicsObject;
import edu.gatech.cs2335.lemmings.physics.PhysicsEngine;
/**
* Class PrettySprite: This is basically an eye-candy sprite. These
* will be things that happen to lemmings, for instance, or maybe some
* other effects, like a random bird flying by.
*
* <PRE>
* Revision History:
* v1.0 (Apr. 11, 2004) - Created the PrettySprite class
* </PRE>
*
* @author <A HREF="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</A>
* @version Version 1.0, Apr. 11, 2004
*/
public abstract class PrettySprite extends PhysicsObject
implements ICleanable {
/**
* The animation associated with this sprite.
*/
private AnimatedSprite animation;
/**
* The level that the sprite is associated with.
*/
private Level level;
/**
* Creates a new <code>PrettySprite</code> instance.
*@param animType anime
*/
public PrettySprite(String animType) {
level = null;
animation = new AnimatedSprite(TileSetManager.getInstance()
.getTileSet(animType),
Direction.NO_DIRECTION,
Looping.INFINITE);
}
/**
* Access method for the animation property.
*
* @return the current value of the animation property
*/
public AnimatedSprite getAnimation() {
return animation;
}
/**
* Describe <code>setAnimation</code> method here.
*
* @param type a <code>String</code> value
*/
public final void setAnimation(String type) {
animation.setAnimation(TileSetManager.getInstance().getTileSet(type));
}
/**
* Should be called at every frame to update the sprite.
*/
public final void updateSprite() {
//Process my own special:
//specialUpdate();
//Update position:
try {
PhysicsEngine.getInstance().calculateNextPoint(this);
} catch (Exception e) {
return;
}
//Update animation:
animation.nextFrameNumber();
//Check if we are ready to die:
if (canKillSelf()) {
//Commit suicide:
level.killPrettySprite(this);
}
}
/**
* Describe <code>getLevel</code> method here.
*
* @return a <code>Level</code> value
*/
public final Level getLevel() {
return level;
}
/**
* Describe <code>setLevel</code> method here.
*
* @param l a <code>Level</code> value
*/
public final void setLevel(Level l) {
level = l;
}
/**
* Cleans up all references for the garbage collector.
*/
public void cleanUp() {
level = null;
animation = null;
}
/**
* Should return true when the sprite is ready to kill self.
*
* @return a <code>boolean</code> value
*/
protected abstract boolean canKillSelf();
}

View File

@@ -0,0 +1,49 @@
package edu.gatech.cs2335.lemmings.engine;
/**
* This class will essentially run the Lemmings game. It is the driver.
*
* @author <A HREF="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</A>
* @version 1.0
*/
public class ProgramRunner {
//@roseuid 406519600375
/**
* Creates a new instance of the runner.
*
*/
private ProgramRunner() { }
//@roseuid 406515D202EA
/**
* Runs the game.
*
*/
public void execute() {
if (GameEngine.VERBOSE) {
System.out.println("The program is running...");
System.out.flush();
}
//Create Splash Screen State:
AbstractGameState gs = new SplashScreenState();
//gs.initialize();
//Start up the game:
GameEngine.getInstance().setCurrentState(gs);
}
/**
* Main method.
*
* @param args a <code>String[]</code> value
*/
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
new ProgramRunner().execute();
}
});
}
}

View File

@@ -0,0 +1,38 @@
package edu.gatech.cs2335.lemmings.engine;
/**
* Class SavedLemming: This thing will basically show the animation of
* the lemming going upstairs into the exit.
*
* <PRE>
* Revision History:
* v1.0 (Apr. 11, 2004) - Created the SavedLemming class
* </PRE>
*
* @author <A HREF="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</A>
* @version Version 1.0, Apr. 11, 2004
*/
public class SavedLemming extends PrettySprite {
/**
* Creates a new <code>SavedLemming</code> instance.
*/
public SavedLemming() {
super("saved_lemming");
}
/**
* Should return true when the sprite is ready to kill self.
*
* @return a <code>boolean</code> value
*/
protected boolean canKillSelf() {
if (getAnimation().getCurrentFrame() == 0) {
//The animation is through. We are done:
return true;
}
return false;
}
}

View File

@@ -0,0 +1,91 @@
package edu.gatech.cs2335.lemmings.engine;
import java.awt.Point;
import java.awt.event.ActionEvent;
import edu.gatech.cs2335.lemmings.gui.LButton;
import edu.gatech.cs2335.lemmings.gui.LRootPane;
import edu.gatech.cs2335.lemmings.graphics.Looping;
import edu.gatech.cs2335.lemmings.graphics.Direction;
import edu.gatech.cs2335.lemmings.graphics.AnimatedSprite;
import edu.gatech.cs2335.lemmings.graphics.TileSetManager;
/**
* This state basically represents the splash screen. It's just a
* fancy graphics, which when the player clicks, disappears.
*
* @author <A HREF="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</A>
*/
public class SplashScreenState extends AbstractGameState {
/**
* Creates a new <code>SplashScreenState</code> instance.
*
*/
public SplashScreenState() {
//Make sure that the resources we want are loaded:
TileSetManager.getInstance().getTileSet("splash");
}
//@roseuid 4065D29C032F
/**
* This method will initialize the state that it belongs to. It will
* then return true upon success, and false upon failure.
*
* @return boolean
*
*/
public boolean initialize() {
LRootPane np = new LRootPane();
LButton button = new LButton();
button.setImage(new AnimatedSprite(TileSetManager.getInstance()
.getTileSet("splash"),
Direction.NO_DIRECTION, Looping.NONE));
button.addActionListener(this);
button.setShown(true);
button.setPosition(new Point(0, 0));
np.addChild(button);
setUI(np);
return true;
}
//@roseuid 4065D29C034D
/**
* This method will perform all of the necessary clean up operations
* once the object is no longer needed.
*
* @return boolean
*
*/
public boolean cleanUp() {
return true;
}
//@roseuid 4065D29C037F
/**
* This function essentially processes the action event that may
* have been thrown by the UI.
*
* @param ae ae
*
*
*/
public void actionPerformed(ActionEvent ae) {
//The splash screen has been clicked.
if (GameEngine.VERBOSE) {
System.out.println("SplashScreenState: Transferrring to Main Menu...");
System.out.flush();
}
//Transfer to Main Menu.
MainMenuState mms = new MainMenuState();
// mms.initialize();
GameEngine.getInstance().setCurrentState(mms);
}
}

View File

@@ -0,0 +1,105 @@
package edu.gatech.cs2335.lemmings.engine;
import java.util.Random;
/**
* Class Particle: When a lemming blows up, he makes particles. Well,
* here they are. :)
*
* Description from Jose:
* Adds specific blood stuff
*
* Blood shouldn't bounce, rather it should hit the wall and die
*
* <PRE>
* Revision History:
* v1.0 (Apr. 11, 2004) - Created the BloodParticle class
* </PRE>
*
* @author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose Caban</A>
* @version Version 1.0, Apr. 11, 2004
*/
public class WaterParticle extends Particle {
/**
* Used to randomize velocity.
*/
private static final Random GENERATOR = new Random(new java.util.Date()
.getTime());
/**
* Particles to create when death should occur
*/
public static final int PARTICLESWHENDIE = 50;
/**
* time to Live
*/
private int killMe;
/**
* curve
*/
private int curve;
/**
* Stores canDie
*/
private boolean canDie;
/**
* Creates a new <code>Particle</code> instance.
*/
public WaterParticle() {
super("water");
getVelocity().setPolar(GENERATOR.nextInt(8), GENERATOR.nextInt(30));
canDie = false;
killMe = 0;
curve = 0;
}
/**
* Should return canDie
*
* @return <code>boolean</code> value
*/
public boolean getCanDie() {
return canDie;
}
/**
* Should return canDie
*
* @param a for candie <code>boolean</code> value
*/
public void setCanDie(boolean a) {
canDie = a;
}
/**
* Should return true when the sprite is ready to kill self.
*
* @return a <code>boolean</code> value
*/
protected boolean canKillSelf() {
if (killMe > 25) {
return true;
}
if (curve > 1) {
return true;
} else if (this.getVelocity().getJ() == 0) {
curve++;
}
killMe++;
return canDie;
}
}

View File

@@ -0,0 +1,149 @@
package edu.gatech.cs2335.lemmings.engine.lemmingjob;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import edu.gatech.cs2335.lemmings.physics.PhysicsEngine;
import edu.gatech.cs2335.lemmings.physics.PhysicsSettings;
import edu.gatech.cs2335.lemmings.physics.PhysicsVector;
import edu.gatech.cs2335.lemmings.physics.Point;
import edu.gatech.cs2335.lemmings.engine.Map;
import edu.gatech.cs2335.lemmings.engine.MapSettings;
import edu.gatech.cs2335.lemmings.engine.Lemming;
import edu.gatech.cs2335.lemmings.engine.GameEngine;
import edu.gatech.cs2335.lemmings.engine.GamePlayState;
import edu.gatech.cs2335.lemmings.engine.DirtParticle;
import edu.gatech.cs2335.lemmings.engine.PrettySprite;
//import edu.gatech.cs2335.lemmings.engine.Level;
/**
* This class represents a lemming job. Essentially, it defines what
* the lemming does in the world, what kind of effect it has, etc.
*
* v1.5 - Jose Caban - added process() handling
* TOnotDO: correct problem with non-breakable areas
* getting nicked slightly
*
*
* @author <a href="mailto:gtg184g@mail.gatech.edu">Jose Caban</a>
* @author <a href="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</a>
* @version 1.5
*/
public class BasherJob extends LemmingJob {
/**
* The Rectangle used to break the gameMap
*/
private Rectangle rectangle;
/**
* Creates a new <code>BasherJob</code> instance.
*
*/
public BasherJob() {
super(LemmingJobSettings.JOB_ID_BASHER);
rectangle = new Rectangle(5, 40);
}
/**
* Processes the effect of the lemming on the world, as well as the
* lemming's position in the world.
*
*/
public void process() {
BufferedImage currentMap = PhysicsEngine.getInstance().getCurrentMap();
Map map = ((GamePlayState) GameEngine.getInstance()
.getCurrentState()).getLevel().getMap();
Lemming lem = this.getOwner();
PhysicsVector currentVelocity = lem.getVelocity();
Point currentPoint = lem.getPosition();
//going to check whether or not this lemming can still be a basher
int rayI = currentPoint.getX();
// int max = LemmingJobSettings.BASHDISTANCE + rayI;
if (LemmingJobSettings.BDEBUG) {
System.out.println("Calculating Basher Stuff...");
System.out.println("rayI1..." + rayI);
System.out.println("currentVelocity..." + currentVelocity.getI());
}
if (currentVelocity.getI() > 0) {
currentVelocity.setI(1);
for (int i = 0; i < LemmingJobSettings.BASHDISTANCE; rayI++, i++) {
if (currentMap.getRGB(rayI, currentPoint.getY())
== MapSettings.getInstance().getUnbreakableColor()) {
lem.setOccupation(LemmingJobSettings.JOB_ID_WALKER);
currentVelocity.setI(PhysicsSettings.getInitialX());
return;
} else if (currentMap.getRGB(rayI, currentPoint.getY())
!= MapSettings.getInstance().getPassableColor()) {
if (LemmingJobSettings.BDEBUG) {
System.out.println("rayI..." + rayI);
}
rectangle.x = currentPoint.getX();
rectangle.y = currentPoint.getY() - 39;
map.subtractShape(rectangle);
//Make the debris
PrettySprite ps;
for (int j = 0; j < DirtParticle.PARTICLESWHENDIG; j++) {
ps =
new DirtParticle(currentVelocity.getI(),
currentVelocity.getJ());
ps.getPosition().setPoint(getOwner().getPosition().getX(),
getOwner().getPosition().getY() - 20,
getOwner().getPosition().getZ());
((GamePlayState) GameEngine.getInstance()
.getCurrentState()).getLevel().addPrettySprite(ps);
}
return;
}
}
} else {
currentVelocity.setI(-1);
for (int i = LemmingJobSettings.BASHDISTANCE; i > 0; rayI--, i--) {
if (currentMap.getRGB(rayI, currentPoint.getY())
== MapSettings.getInstance().getUnbreakableColor()) {
lem.setOccupation(LemmingJobSettings.JOB_ID_WALKER);
currentVelocity.setI(-PhysicsSettings.getInitialX());
return;
} else if (currentMap.getRGB(rayI, currentPoint.getY())
!= MapSettings.getInstance().getPassableColor()) {
if (LemmingJobSettings.BDEBUG) {
System.out.println("rayI2..." + rayI);
}
rectangle.x = currentPoint.getX() - rectangle.width;
rectangle.y = currentPoint.getY() - 39;
map.subtractShape(rectangle);
//Make the debris
PrettySprite ps;
for (int j = 0; j < DirtParticle.PARTICLESWHENDIG; j++) {
ps = new DirtParticle(currentVelocity.getI(), currentVelocity.getJ());
ps.getPosition().setPoint(getOwner().getPosition().getX(),
getOwner().getPosition().getY(),
getOwner().getPosition().getZ());
((GamePlayState) GameEngine.getInstance()
.getCurrentState()).getLevel().addPrettySprite(ps);
}
return;
}
}
}
lem.setOccupation(LemmingJobSettings.JOB_ID_WALKER);
}
}

View File

@@ -0,0 +1,83 @@
package edu.gatech.cs2335.lemmings.engine.lemmingjob;
//import java.awt.geom.Ellipse2D;
//import java.awt.geom.Ellipse2D.Float;
//import java.awt.image.BufferedImage;
import java.util.List;
//import edu.gatech.cs2335.lemmings.physics.PhysicsEngine;
//import edu.gatech.cs2335.lemmings.physics.PhysicsSettings;
//import edu.gatech.cs2335.lemmings.physics.PhysicsVector;
import edu.gatech.cs2335.lemmings.physics.Point;
//import edu.gatech.cs2335.lemmings.engine.Map;
//import edu.gatech.cs2335.lemmings.engine.MapSettings;
import edu.gatech.cs2335.lemmings.engine.Lemming;
import edu.gatech.cs2335.lemmings.engine.GameEngine;
import edu.gatech.cs2335.lemmings.engine.GamePlayState;
import edu.gatech.cs2335.lemmings.engine.Level;
/**
* This class represents a lemming job. Essentially, it defines what
* the lemming does in the world, what kind of effect it has, etc.
*
* v1.5 Jose - Completed Blocker
*
* @author <a href="mailto:gtg184g@mail.gatech.edu">Jose Caban</a>
* @author <a href="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</a>
* @version 1.5
*/
public class BlockerJob extends LemmingJob {
/**
* Creates a new <code>BlockerJob</code> instance.
*
*/
public BlockerJob() {
super(LemmingJobSettings.JOB_ID_BLOCKER);
}
/**
* This function will be called whenever the owner is set and it is
* not NULL.
*/
protected void onSetOwner() {
getOwner().getVelocity().setI(0);
getOwner().updateDirection();
}
/**
* Processes the effect of the lemming on the world, as well as the
* lemming's position in the world.
*/
public void process() {
Level level
= ((GamePlayState) GameEngine.getInstance().getCurrentState()).getLevel();
Lemming lem = this.getOwner();
Point blockerPoint = lem.getPosition();
List list = level.getActiveLemmings();
Lemming currLem;
Point currentPoint;
for (int i = 0; i < list.size(); i++) {
currLem = (Lemming) list.get(i);
currentPoint = currLem.getPosition();
if (Math.abs(blockerPoint.getX() - currentPoint.getX())
< LemmingJobSettings.BLOCKERTOLERANCE
&& Math.abs(blockerPoint.getY() - currentPoint.getY())
< LemmingJobSettings.BLOCKERTOLERANCE) {
if (Math.abs(currentPoint.getX() + currLem.getVelocity().getI()
- blockerPoint.getX())
> Math.abs(currentPoint.getX() - blockerPoint.getX())) {
return;
}
currLem.getVelocity().setI(-1 * currLem.getVelocity().getI());
currLem.updateDirection();
}
}
}
}

View File

@@ -0,0 +1,133 @@
package edu.gatech.cs2335.lemmings.engine.lemmingjob;
import java.awt.Rectangle;
//import java.awt.image.BufferedImage;
import java.awt.Color;
//import edu.gatech.cs2335.lemmings.physics.PhysicsEngine;
//import edu.gatech.cs2335.lemmings.physics.PhysicsSettings;
import edu.gatech.cs2335.lemmings.physics.PhysicsVector;
import edu.gatech.cs2335.lemmings.physics.Point;
import edu.gatech.cs2335.lemmings.engine.Map;
//import edu.gatech.cs2335.lemmings.engine.MapSettings;
import edu.gatech.cs2335.lemmings.engine.Lemming;
import edu.gatech.cs2335.lemmings.engine.GameEngine;
import edu.gatech.cs2335.lemmings.engine.GamePlayState;
//import edu.gatech.cs2335.lemmings.engine.Level;
/**
* This class represents a lemming job. Essentially, it defines what
* the lemming does in the world, what kind of effect it has, etc.
*
* v1.4 - Turn around stop bridging
*
* v1.2 - Basic Bridging
*
* @author <a href="mailto:gtg184g@mail.gatech.edu">Jose Caban</a>
* @author <a href="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</a>
* @version 1.4
*/
public class BridgerJob extends LemmingJob {
/**
* Stores the current number of bricks laid down
*/
private int bricks;
/**
* Stores the current wait time
*/
private int waitTime;
/**
* The rectangle brick
*/
private Rectangle rectangle;
/**
* The direction
*/
private int direction;
/**
* Creates a new <code>BridgerJob</code> instance.
*
*/
public BridgerJob() {
super(LemmingJobSettings.JOB_ID_BRIDGER);
rectangle = new Rectangle(10, 2);
bricks = 0;
direction = 0;
waitTime = 0;
}
/**
* Processes the effect of the lemming on the world, as well as the
* lemming's position in the world.
*/
public void process() {
// BufferedImage currentMap = PhysicsEngine.
//getInstance().getCurrentMap();
Map map = ((GamePlayState) GameEngine.getInstance()
.getCurrentState()).getLevel().getMap();
Lemming lem = this.getOwner();
PhysicsVector currentVelocity = lem.getVelocity();
Point currentPoint = lem.getPosition();
if (direction == 0) {
direction = (currentVelocity.getI() > 0) ? 1 : -1;
} else if (currentVelocity.getI() > 0 && direction != 1) {
lem.setOccupation(LemmingJobSettings.JOB_ID_WALKER);
return;
} else if (currentVelocity.getI() < 0 && direction != -1) {
lem.setOccupation(LemmingJobSettings.JOB_ID_WALKER);
return;
}
if (bricks == 72) {
currentVelocity.setI(0);
if (waitTime >= LemmingJobSettings.BRIDGERDONETIME) {
lem.setOccupation(LemmingJobSettings.JOB_ID_WALKER);
}
if (LemmingJobSettings.BDEBUG) {
System.out.println("waitTime: " + waitTime);
}
waitTime++;
return;
}
if (currentVelocity.getI() > 0) {
if (bricks % 3 == 0) {
rectangle.x = currentPoint.getX() + rectangle.width;
rectangle.y = currentPoint.getY();
map.addShape(rectangle, Color.PINK);
}
bricks++;
} else {
if (bricks % 3 == 0) {
rectangle.x = currentPoint.getX()
- (rectangle.width * 2);
rectangle.y = currentPoint.getY();
map.addShape(rectangle, Color.PINK);
}
bricks++;
}
}
/**
*accessort
*@return int
*/
public int getDirection() {
return (this.direction);
}
}

View File

@@ -0,0 +1,96 @@
package edu.gatech.cs2335.lemmings.engine.lemmingjob;
//import java.awt.image.BufferedImage;
//import edu.gatech.cs2335.lemmings.physics.PhysicsEngine;
//import edu.gatech.cs2335.lemmings.physics.PhysicsSettings;
//import edu.gatech.cs2335.lemmings.physics.PhysicsVector;
//import edu.gatech.cs2335.lemmings.physics.Point;
//import edu.gatech.cs2335.lemmings.engine.Map;
//import edu.gatech.cs2335.lemmings.engine.MapSettings;
import edu.gatech.cs2335.lemmings.engine.Lemming;
//import edu.gatech.cs2335.lemmings.engine.GameEngine;
//import edu.gatech.cs2335.lemmings.engine.GamePlayState;
//import edu.gatech.cs2335.lemmings.engine.Level;
/**
* This class represents a lemming job. Essentially, it defines what
* the lemming does in the world, what kind of effect it has, etc.
*
* @author <a href="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</a>
* @version 1.0
*/
public class ClimberJob extends LemmingJob {
/**
*
*/
private boolean isClimbing;
/**
* the lemming direction
*/
private int direction;
/**
* Creates a new <code>ClimberJob</code> instance.
*
*/
public ClimberJob() {
super(LemmingJobSettings.JOB_ID_CLIMBER,
LemmingJobSettings.JOB_ID_CLIMBER + "_"
+ LemmingJobSettings.REGULAR_FALLER);
}
/**
* Processes the effect of the lemming on the world, as well as the
* lemming's position in the world.
*/
public void process() {
if (((Lemming) this.getOwner()).getVelocity().getI() > 0) {
direction = 1;
} else if (((Lemming) this.getOwner()).getVelocity().getI() < 0) {
direction = -1;
}
}
/**
* Method setIsClimbing
*
*
* @param isClimbing boolean
*
*/
public void setIsClimbing(boolean isClimbing) {
this.isClimbing = isClimbing;
}
/**
* Method getIsClimbing
*
*
* @return boolean , whether or not the lemming is climbing
*
*/
public boolean isClimbing() {
return (this.isClimbing);
}
/**
*mutator
*@param direction direction
*/
public void setDirection(int direction) {
this.direction = direction;
}
/**
*accessor
*@return int
*/
public int getDirection() {
return (this.direction);
}
}

View File

@@ -0,0 +1,111 @@
package edu.gatech.cs2335.lemmings.engine.lemmingjob;
import java.awt.geom.Ellipse2D;
//import java.awt.geom.Ellipse2D.Float;
import java.awt.image.BufferedImage;
import edu.gatech.cs2335.lemmings.physics.PhysicsEngine;
//import edu.gatech.cs2335.lemmings.physics.PhysicsSettings;
import edu.gatech.cs2335.lemmings.physics.PhysicsVector;
import edu.gatech.cs2335.lemmings.physics.Point;
import edu.gatech.cs2335.lemmings.engine.Map;
import edu.gatech.cs2335.lemmings.engine.MapSettings;
import edu.gatech.cs2335.lemmings.engine.Lemming;
import edu.gatech.cs2335.lemmings.engine.GameEngine;
import edu.gatech.cs2335.lemmings.engine.GamePlayState;
import edu.gatech.cs2335.lemmings.engine.DirtParticle;
import edu.gatech.cs2335.lemmings.engine.PrettySprite;
//import edu.gatech.cs2335.lemmings.engine.Level;
/**
* This class represents a lemming job. Essentially, it defines what
* the lemming does in the world, what kind of effect it has, etc.
*
* v1.5 - Jose Caban - added process() handling
* TOnotDO: correct problem with non-breakable areas
* getting nicked slightly
*
*
* @author <a href="mailto:gtg184g@mail.gatech.edu">Jose Caban</a>
* @author <a href="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</a>
* @version 1.5
*/
public class DiggerJob extends LemmingJob {
/**
* Dig a Circle!
*/
private Ellipse2D.Float circle;
/**
* Creates a new <code>DiggerJob</code> instance.
*
*/
public DiggerJob() {
super(LemmingJobSettings.JOB_ID_DIGGER);
circle = new Ellipse2D.Float(0, 0, 20, 10);
}
/**
* Processes the effect of the lemming on the world, as well as the
* lemming's position in the world.
*/
public void process() {
BufferedImage currentMap = PhysicsEngine.getInstance().getCurrentMap();
Map map = ((GamePlayState) GameEngine.getInstance()
.getCurrentState()).getLevel().getMap();
Lemming lem = this.getOwner();
PhysicsVector currentVelocity = lem.getVelocity();
Point currentPoint = lem.getPosition();
//going to check whether or not this lemming can still be a basher
int rayJ = currentPoint.getY();
if (LemmingJobSettings.BDEBUG) {
System.out.println("Calculating Basher Stuff...");
System.out.println("rayJ1..." + rayJ);
System.out.println("currentVelocity..." + currentVelocity.getJ());
}
for (int i = 0; i < LemmingJobSettings.DIGDISTANCE; rayJ++, i++) {
if (currentMap.getRGB(currentPoint.getX(), rayJ) == MapSettings
.getInstance().getUnbreakableColor()) {
lem.setOccupation(LemmingJobSettings.JOB_ID_WALKER);
return;
} else if (currentMap.getRGB(currentPoint.getX(), rayJ)
!= MapSettings.getInstance().getPassableColor()) {
if (LemmingJobSettings.BDEBUG) {
System.out.println("rayJ..." + rayJ);
}
circle.x = currentPoint.getX() - (circle.width) / 2;
circle.y = currentPoint.getY() - (circle.height) / 2;
map.subtractShape(circle);
//Make the debris
PrettySprite ps;
for (int j = 0; j < DirtParticle.PARTICLESWHENDIG; j++) {
ps = new DirtParticle(currentVelocity.getI(), currentVelocity.getJ());
ps.getPosition().setPoint(getOwner().getPosition().getX(),
getOwner().getPosition().getY(),
getOwner().getPosition().getZ());
((GamePlayState) GameEngine.getInstance()
.getCurrentState()).getLevel().addPrettySprite(ps);
}
return;
}
}
lem.setOccupation(LemmingJobSettings.JOB_ID_WALKER);
}
}

View File

@@ -0,0 +1,91 @@
package edu.gatech.cs2335.lemmings.engine.lemmingjob;
import java.awt.geom.Ellipse2D;
//import java.awt.geom.Ellipse2D.Float;
//import java.awt.image.BufferedImage;
//import edu.gatech.cs2335.lemmings.physics.PhysicsEngine;
//import edu.gatech.cs2335.lemmings.physics.PhysicsSettings;
//import edu.gatech.cs2335.lemmings.physics.PhysicsVector;
import edu.gatech.cs2335.lemmings.physics.Point;
//import edu.gatech.cs2335.lemmings.engine.Map;
//import edu.gatech.cs2335.lemmings.engine.MapSettings;
import edu.gatech.cs2335.lemmings.engine.Lemming;
import edu.gatech.cs2335.lemmings.engine.GameEngine;
import edu.gatech.cs2335.lemmings.engine.GamePlayState;
import edu.gatech.cs2335.lemmings.engine.Level;
//import edu.gatech.cs2335.lemmings.graphics.TileSet;
/**
* This class represents a lemming job. Essentially, it defines what
* the lemming does in the world, what kind of effect it has, etc.
*
* v1.2 - Basic Exploding
*
* @author <a href="mailto:gtg184g@mail.gatech.edu">Jose Caban</a>
* @author <a href="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</a>
* @version 1.2
*/
public class ExploderJob extends LemmingJob {
/**
* Time to blow
*/
private int timeLeftOnEarth;
/**
* Explosion thing
*/
private Ellipse2D.Float circle;
/**
* The tileset with the numbers.
*/
// private TileSet numbers;
/**
* Creates a new <code>ExploderJob</code> instance.
*
*/
public ExploderJob() {
super(LemmingJobSettings.JOB_ID_EXPLODER);
timeLeftOnEarth = LemmingJobSettings.BLOWUPTIME;
circle = new Ellipse2D.Float(0, 0,
LemmingJobSettings.EXPLOSIONDIAMETER,
LemmingJobSettings.EXPLOSIONDIAMETER);
}
/**
* Describe <code>getTimeLeftOnEarth</code> method here.
*
* @return an <code>int</code> value
*/
public int getTimeLeftOnEarth() {
return timeLeftOnEarth;
}
/**
* Processes the effect of the lemming on the world, as well as the
* lemming's position in the world.
*/
public void process() {
if (timeLeftOnEarth == 0) {
Level level = ((GamePlayState) GameEngine.getInstance()
.getCurrentState()).getLevel();
Lemming lem = this.getOwner();
Point currentPoint = lem.getPosition();
circle.x = currentPoint.getX() - (circle.width / 2);
circle.y = currentPoint.getY() - (circle.width / 2) - 6;
level.getMap().subtractShape(circle);
level.killLemming(lem, false);
}
timeLeftOnEarth--;
}
}

View File

@@ -0,0 +1,29 @@
package edu.gatech.cs2335.lemmings.engine.lemmingjob;
/**
* This class represents a lemming job. Essentially, it defines what
* the lemming does in the world, what kind of effect it has, etc.
*
* @author <a href="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</a>
* @version 1.0
*/
public class FloaterJob extends LemmingJob {
/**
* Creates a new <code>FloaterJob</code> instance.
*
*/
public FloaterJob() {
super(LemmingJobSettings.JOB_ID_FLOATER,
LemmingJobSettings.JOB_ID_FLOATER + "_"
+ LemmingJobSettings.REGULAR_FALLER);
}
/**
* Processes the effect of the lemming on the world, as well as the
* lemming's position in the world.
*/
public void process() {
///yeah...
}
}

View File

@@ -0,0 +1,73 @@
package edu.gatech.cs2335.lemmings.engine.lemmingjob;
//import edu.gatech.cs2335.lemmings.physics.PhysicsSettings;
import edu.gatech.cs2335.lemmings.engine.PrettySprite;
import edu.gatech.cs2335.lemmings.engine.FlameParticle;
//import edu.gatech.cs2335.lemmings.engine.*;
import edu.gatech.cs2335.lemmings.engine.GamePlayState;
import edu.gatech.cs2335.lemmings.engine.GameEngine;
/**
* This class represents a lemming job. Essentially, it defines what
* the lemming does in the world, what kind of effect it has, etc.
*
* @author <A HREF="mailto:gtg184g@mail.gatech.edu">Jose Caban</A>
* @author <a href="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</a>
* @version 1.0
*/
public class HandGliderJob extends LemmingJob {
/**
* Used to keep track of when to reset out little AE major
*/
private boolean hasFlown;
/**
* Creates a new <code>HandGliderJob</code> instance.
*
*/
public HandGliderJob() {
super(LemmingJobSettings.JOB_ID_HAND_GLIDER,
LemmingJobSettings.JOB_ID_HAND_GLIDER + "_"
+ LemmingJobSettings.REGULAR_FALLER);
hasFlown = false;
}
/**
* This function will be called whenever the owner is set and it is
* not NULL.
*/
protected void onSetOwner() {
}
/**
*@return boolean
*/
public boolean hasFlown() {
return hasFlown;
}
/**
*@param b boolean
*/
public void setFlown(boolean b) {
this.hasFlown = b;
}
/**
* Processes the effect of the lemming on the world, as well as the
* lemming's position in the world.
*/
public void process() {
//No need for this, Physics handles it
PrettySprite ps;
for (int i = 0; i < FlameParticle.PARTICLESWHENFLAME; i++) {
ps = new FlameParticle();
ps.getPosition().setPoint(getOwner().getPosition().getX(),
getOwner().getPosition().getY(),
getOwner().getPosition().getZ());
((GamePlayState)
GameEngine.getInstance().getCurrentState()).getLevel().addPrettySprite(ps);
}
}
}

View File

@@ -0,0 +1,37 @@
package edu.gatech.cs2335.lemmings.engine.lemmingjob;
import edu.gatech.cs2335.lemmings.engine.Lemming;
//import edu.gatech.cs2335.lemmings.physics.PhysicsVector;
import edu.gatech.cs2335.lemmings.physics.PhysicsSettings;
/**
* This class represents a lemming job. Essentially, it defines what
* the lemming does in the world, what kind of effect it has, etc.
*
* @author <a href="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</a>
* @version 1.0
*/
public class JumperJob extends LemmingJob {
/**
* Creates a new <code>JumperJob</code> instance.
*
*/
public JumperJob() {
super(LemmingJobSettings.JOB_ID_JUMPER);
}
/**
* Processes the effect of the lemming on the world, as well as the
* lemming's position in the world.
*/
public void process() {
//Jose is a nUb.
Lemming lem = getOwner();
if (lem.getVelocity().getJ() == 0) {
lem.getVelocity().setJ(PhysicsSettings.getInstance().getLaunchSpeed());
lem.setOccupation(LemmingJobSettings.JOB_ID_WALKER);
}
}
}

View File

@@ -0,0 +1,183 @@
package edu.gatech.cs2335.lemmings.engine.lemmingjob;
import edu.gatech.cs2335.lemmings.engine.Lemming;
import edu.gatech.cs2335.lemmings.graphics.Looping;
import edu.gatech.cs2335.lemmings.graphics.Direction;
import edu.gatech.cs2335.lemmings.graphics.TileSetManager;
import edu.gatech.cs2335.lemmings.graphics.AnimatedSprite;
/**
* This class represents a lemming job. Essentially, it defines what
* the lemming does in the world, what kind of effect it has, etc.
*
* @author <a href="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</a>
* @version 1.0
*/
public abstract class LemmingJob {
/**
* The string id of the lemming job.
*/
private String id;
/**
* The lemming, with which this job is associated.
*/
private Lemming owner;
/**
* The regular animation associated with the job.
*/
private AnimatedSprite regularAnimation;
/**
* The falling animation associated with the job.
*/
private AnimatedSprite fallingAnimation;
/**
* Creates a new <code>LemmingJob</code> instance.
*/
protected LemmingJob() {
this(LemmingJobSettings.JOB_ID_WALKER);
}
/**
* Creates a new <code>LemmingJob</code> instance.
*
* @param jobId a <code>String</code> value
*/
protected LemmingJob(String jobId) {
this(jobId, LemmingJobSettings.REGULAR_FALLER);
}
/**
* Creates a new <code>LemmingJob</code> instance.
*
* @param regularId a <code>String</code> value
* @param fallingId a <code>String</code> value
*/
protected LemmingJob(String regularId, String fallingId) {
//Set up Job Id:
id = regularId;
//Set up Owner:
owner = null;
//Set up animations:
regularAnimation
= new AnimatedSprite(TileSetManager.getInstance()
.getTileSet(regularId),
Direction.RIGHT,
Looping.INFINITE);
fallingAnimation = new AnimatedSprite(TileSetManager.getInstance()
.getTileSet(fallingId),
Direction.NO_DIRECTION,
Looping.INFINITE);
}
/**
* Describe <code>cleanUp</code> method here.
*
*/
public void cleanUp() {
id = null;
owner = null;
regularAnimation = null;
fallingAnimation = null;
}
/**
* Access method for the id property.
*
* @return the current value of the id property
*/
public String getId() {
return id;
}
/**
* Access method for the owner property.
*
* @return the current value of the owner property
*/
public Lemming getOwner() {
return owner;
}
/**
* Sets the value of the owner property.
*
* @param aOwner the new value of the owner property
*/
public void setOwner(Lemming aOwner) {
owner = aOwner;
if (owner != null) {
onSetOwner();
}
}
/**
* Access method for the animation property.
*
* @return the current value of the animation property
*/
public AnimatedSprite getAnimation() {
if (owner.getPhysics().isFalling()) {
return fallingAnimation;
} else {
return regularAnimation;
}
}
/**
* Set the value of the regular animation for this lemming.
*
* @param animation an <code>AnimatedSprite</code> value
*/
protected void setRegularAnimation(AnimatedSprite animation) {
regularAnimation.setAnimation(animation.getAnimation());
}
/**
* Describe <code>getRegularAnimation</code> method here.
*
* @return an <code>AnimatedSprite</code> value
*/
public AnimatedSprite getRegularAnimation() {
return regularAnimation;
}
/**
* Describe <code>getFallingAnimation</code> method here.
*
* @return an <code>AnimatedSprite</code> value
*/
public AnimatedSprite getFallingAnimation() {
return fallingAnimation;
}
/**
* Set the value of the falling animation for this lemming.
*
* @param animation an <code>AnimatedSprite</code> value
*/
protected void setFallingAnimation(AnimatedSprite animation) {
fallingAnimation.setAnimation(animation.getAnimation());
}
//@roseuid 4065FCD300AE
/**
* Processes the effect of the lemming on the world, as well as the
* lemming's position in the world.
*
*/
public abstract void process();
/**
* This function will be called whenever the owner is set and it is
* not NULL.
*/
protected void onSetOwner() { }
}

View File

@@ -0,0 +1,85 @@
package edu.gatech.cs2335.lemmings.engine.lemmingjob;
/**
* Creates lemming jobs.
* @author <A HREF="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</A>
* @version 1.0
*/
public class LemmingJobFactory {
/**
* Singleton Implementation.
*/
private static LemmingJobFactory instance;
/**
* Creates a new <code>LemmingJobFactory</code> instance.
*
*/
private LemmingJobFactory() { }
/**
* Access method for the instance property.
*
* @return the current value of the instance property.
*/
public static LemmingJobFactory getInstance() {
if (instance == null) {
instance = new LemmingJobFactory();
}
return instance;
}
//@roseuid 406602CE0394
/**
* Creates a lemming job with the specified id and initializes it
* appropriately.
*
* @param id The id of the job type to create.
* @return The new lemming job.
*
*/
public LemmingJob makeJob(String id) {
LemmingJob result = null;
if (LemmingJobSettings.JOB_ID_BASHER.equals(id)) {
result = new BasherJob();
} else if (LemmingJobSettings.JOB_ID_BLOCKER.equals(id)) {
result = new BlockerJob();
} else if (LemmingJobSettings.JOB_ID_BRIDGER.equals(id)) {
result = new BridgerJob();
} else if (LemmingJobSettings.JOB_ID_CLIMBER.equals(id)) {
result = new ClimberJob();
} else if (LemmingJobSettings.JOB_ID_DIGGER.equals(id)) {
result = new DiggerJob();
} else if (LemmingJobSettings.JOB_ID_EXPLODER.equals(id)) {
result = new ExploderJob();
} else if (LemmingJobSettings.JOB_ID_FLOATER.equals(id)) {
result = new FloaterJob();
} else if (LemmingJobSettings.JOB_ID_HAND_GLIDER.equals(id)) {
result = new HandGliderJob();
} else if (LemmingJobSettings.JOB_ID_JUMPER.equals(id)) {
result = new JumperJob();
} else if (LemmingJobSettings.JOB_ID_MINER.equals(id)) {
result = new MinerJob();
} else if (LemmingJobSettings.JOB_ID_WALKER.equals(id)) {
result = new WalkerJob();
} else {
throw new IllegalArgumentException("Bad job id");
}
return result;
}
}

View File

@@ -0,0 +1,137 @@
package edu.gatech.cs2335.lemmings.engine.lemmingjob;
/**
* Contains some settings for the lemming jobs.
*
* @author <A HREF="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</A>
*/
public final class LemmingJobSettings {
/**
*
*/
public static final boolean BDEBUG = false;
/**
* The id the basher job type.
*/
public static final String JOB_ID_BASHER = "basher";
/**
* The id the blocker job type.
*/
public static final String JOB_ID_BLOCKER = "blocker";
/**
* The id the bridger job type.
*/
public static final String JOB_ID_BRIDGER = "bridger";
/**
* The id the climber job type.
*/
public static final String JOB_ID_CLIMBER = "climber";
/**
* The id the digger job type.
*/
public static final String JOB_ID_DIGGER = "digger";
/**
* The id the exploder job type.
*/
public static final String JOB_ID_EXPLODER = "exploder";
/**
* The id the floater job type.
*/
public static final String JOB_ID_FLOATER = "floater";
/**
* The id the hand_glider job type.
*/
public static final String JOB_ID_HAND_GLIDER = "hand_glider";
/**
* The id the jumper job type.
*/
public static final String JOB_ID_JUMPER = "jumper";
/**
* The id the launcher job type.
*/
public static final String JOB_ID_LAUNCHER = "launcher";
/**
* The id the miner job type.
*/
public static final String JOB_ID_MINER = "miner";
/**
* The id the walker job type.
*/
public static final String JOB_ID_WALKER = "walker";
/**
* The id of the regular faller animation.
*/
public static final String REGULAR_FALLER = "faller";
/**
* Contains all of the job names in a nice little array.
*/
public static final String[] ALL_JOB_NAMES = {
JOB_ID_BASHER,
JOB_ID_BLOCKER,
JOB_ID_BRIDGER,
JOB_ID_CLIMBER,
JOB_ID_DIGGER,
JOB_ID_EXPLODER,
JOB_ID_FLOATER,
JOB_ID_HAND_GLIDER,
JOB_ID_JUMPER,
JOB_ID_LAUNCHER,
JOB_ID_MINER,
JOB_ID_WALKER,
};
/**
* The max distance between a basher and a wall to bash
*/
public static final int BASHDISTANCE = 75;
/**
* The distance to the point to dig
*/
public static final int DIGDISTANCE = 8;
/**
* The distance to the point to mine
*/
public static final int MINEDISTANCE = 20;
/**
* Time to blow
*/
public static final int BLOWUPTIME = 30;
/**
* Explosion Diameter
*/
public static final int EXPLOSIONDIAMETER = 42;
/**
* Blocker Tolerance (distance to change direction)
*/
public static final int BLOCKERTOLERANCE = 10;
/**
* Bridger wait time
*/
public static final int BRIDGERDONETIME = 50;
/**
* Creates a new <code>LemmingJobSettings</code> instance.
*/
private LemmingJobSettings() { }
}

View File

@@ -0,0 +1,142 @@
package edu.gatech.cs2335.lemmings.engine.lemmingjob;
import java.awt.geom.Ellipse2D;
//import java.awt.geom.Ellipse2D.Float;
import java.awt.image.BufferedImage;
import edu.gatech.cs2335.lemmings.physics.PhysicsEngine;
//import edu.gatech.cs2335.lemmings.physics.PhysicsSettings;
import edu.gatech.cs2335.lemmings.physics.PhysicsVector;
import edu.gatech.cs2335.lemmings.physics.Point;
import edu.gatech.cs2335.lemmings.engine.Map;
import edu.gatech.cs2335.lemmings.engine.MapSettings;
import edu.gatech.cs2335.lemmings.engine.Lemming;
import edu.gatech.cs2335.lemmings.engine.GameEngine;
import edu.gatech.cs2335.lemmings.engine.GamePlayState;
import edu.gatech.cs2335.lemmings.engine.DirtParticle;
import edu.gatech.cs2335.lemmings.engine.PrettySprite;
//import edu.gatech.cs2335.lemmings.engine.Level;
/**
* This class represents a lemming job. Essentially, it defines what
* the lemming does in the world, what kind of effect it has, etc.
*
* v1.5 - Jose Caban - added process() handling
* TOnotDO: correct problem with non-breakable areas
* getting nicked slightly
*
*
* @author <a href="mailto:gtg184g@mail.gatech.edu">Jose Caban</a>
* @author <a href="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</a>
* @version 1.5
*/
public class MinerJob extends LemmingJob {
/**
* Dig a Circle!
*/
private Ellipse2D.Float circle;
/**
* Creates a new <code>MinerJob</code> instance.
*
*/
public MinerJob() {
super(LemmingJobSettings.JOB_ID_MINER);
circle = new Ellipse2D.Float(0, 0, 20, 10);
}
/**
* Processes the effect of the lemming on the world, as well as the
* lemming's position in the world.
*/
public void process() {
BufferedImage currentMap = PhysicsEngine.getInstance().getCurrentMap();
Map map = ((GamePlayState) GameEngine.getInstance()
.getCurrentState()).getLevel().getMap();
Lemming lem = this.getOwner();
PhysicsVector currentVelocity = lem.getVelocity();
Point currentPoint = lem.getPosition();
//going to check whether or not this lemming can still be a basher
int rayI = currentPoint.getX();
// int max = LemmingJobSettings.MINEDISTANCE + rayI;
if (LemmingJobSettings.BDEBUG) {
System.out.println("Calculating Miner Stuff...");
System.out.println("rayI1..." + rayI);
System.out.println("currentVelocity..." + currentVelocity.getI());
}
boolean bFoundDirt = false;
if (currentVelocity.getI() > 0) {
for (int i = 0; i < LemmingJobSettings.MINEDISTANCE; rayI++, i++) {
if (currentMap.getRGB(rayI, currentPoint.getY() + i)
== MapSettings.getInstance().getUnbreakableColor()) {
lem.setOccupation(LemmingJobSettings.JOB_ID_WALKER);
return;
} else if (currentMap.getRGB(rayI, currentPoint.getY() + i)
!= MapSettings.getInstance().getPassableColor()) {
bFoundDirt = true;
if (LemmingJobSettings.BDEBUG) {
System.out.println("rayI..." + rayI);
}
}
if (LemmingJobSettings.BDEBUG) {
System.out.println("Currently at " + rayI
+ (currentPoint.getY() + i));
}
}
if (bFoundDirt) {
circle.x = currentPoint.getX();
circle.y = currentPoint.getY();
map.subtractShape(circle);
//Make the debris
PrettySprite ps;
for (int j = 0; j < DirtParticle.PARTICLESWHENDIG; j++) {
ps = new DirtParticle(currentVelocity.getI(), currentVelocity.getJ());
ps.getPosition().setPoint(getOwner().getPosition().getX(),
getOwner().getPosition().getY(),
getOwner().getPosition().getZ());
((GamePlayState) GameEngine.getInstance()
.getCurrentState()).getLevel().addPrettySprite(ps);
}
return;
}
} else {
for (int i = 0; i < LemmingJobSettings.MINEDISTANCE; rayI--, i++) {
if (currentMap.getRGB(rayI, currentPoint.getY() + i)
== MapSettings.getInstance().getUnbreakableColor()) {
lem.setOccupation(LemmingJobSettings.JOB_ID_WALKER);
return;
} else if (currentMap.getRGB(rayI, currentPoint.getY() + i)
!= MapSettings.getInstance().getPassableColor()) {
bFoundDirt = true;
}
if (LemmingJobSettings.BDEBUG) {
System.out.println("Currently at " + rayI
+ (currentPoint.getY() + i));
}
}
if (bFoundDirt) {
circle.x = currentPoint.getX() - 20;
circle.y = currentPoint.getY();
map.subtractShape(circle);
return;
}
}
lem.setOccupation(LemmingJobSettings.JOB_ID_WALKER);
}
}

View File

@@ -0,0 +1,44 @@
package edu.gatech.cs2335.lemmings.engine.lemmingjob;
import edu.gatech.cs2335.lemmings.physics.PhysicsSettings;
/**
* This class represents a lemming job. Essentially, it defines what
* the lemming does in the world, what kind of effect it has, etc.
*
* @author <a href="mailto:gtg308i@mail.gatech.edu">Vladimir Urazov</a>
* @version 1.0
*/
public class WalkerJob extends LemmingJob {
/**
* Creates a new <code>WalkerJob</code> instance.
*
*/
public WalkerJob() {
super();
}
/**
* This function will be called whenever the owner is set and it is
* not NULL.
*/
protected void onSetOwner() {
if (getOwner().getVelocity().getI() >= 0) {
getOwner().getVelocity().setI(PhysicsSettings.getInstance()
.getInitialX());
} else {
getOwner().getVelocity().setI(-PhysicsSettings.getInstance()
.getInitialX());
}
}
/**
* Processes the effect of the lemming on the world, as well as the
* lemming's position in the world.
*/
public void process() {
//Since this is a plain walker lemming, there is really nothing to
//do here.
}
}