| Revision History | ||
|---|---|---|
| Revision 1.0 | 2004-2-16 | TC |
| Initial release in DocBook format. | ||
Table of Contents
![]() |
Warning |
|---|---|
While this project is intended to be completed by a "team effort" it is important to remember that only members of YOUR team may contribute to YOUR project. This means that you may not "share" or "borrow" code or design solutions with ANYONE (this includes all individuals not affiliated with this class), EXCEPT members of YOUR team and official CS2335 teaching staff. The CS2335 TA's are well aware that Lemmings implementations are widely available (on the web and otherwise). Using or referencing the source code or design documents from any of these implementations is strictly prohibited. Including any materials associated with these implementations in your submission is strictly prohibited. De-compilation of any byte/object code is strictly prohibited. It should be noted that using material written by another individual in violation of a copyright or patent is a crime and subject to criminal/civil prosecution (see U.S. copyright law, U.S. patent law). College of Computing staff will be comparing all submissions in an effort to identify any individuals who are involved in academic misconduct. In addition your submission will be compared to those otherwise available (via the web or otherwise). A "CHEAT-FINDER" WILL BE USED AND IT WILL COMPARE YOUR SUBMISSION TO OTHER STUDENTS' SUBMISSIONS AND THOSE AVAILABLE ON THE WEB - IF YOU CHEAT YOU WILL BE CAUGHT. Any activities that give a team an unfair advantage over any other team are considered academic misconduct (see Georgia Institute of Technology Academic Honor Code). The College of Computing plans to prosecute all cases of academic misconduct in this class. If the College of Computing staff has reason to believe that any state or federal law has been violated, appropriate law enforcement officials may be notified. If you have any concerns about which resources may or may not be used, you should contact your CS2335 TA. If you know of outside resources (third-party libraries, etc.) that could be helpful, your TA can make them available. |
|
In 1991, Psygnosis published a game called "Lemmings" for the Amiga, followed by releases for the PC and Macintosh. Lemmings was an unusual puzzle game, but it was a real hit. "Oh No! More Lemmings" came out shortly thereafter with a new levelset on top of the old engine. In 1993, "Lemmings 2: The Tribes" was released. It had the same basic gameplay and graphical style as the original, but with an updated engine with new maps and abilities. Later games included "Lemmings Chronicles," "All New World of Lemmings," "3D Lemmings," "Lemmings Paintball," and " Lemmings Revolution." All the games but Paintball kept the same general idea, though sometimes (as with 3D Lemmings) the gameplay was radically different.
History taken from http://www.utahdesign.com/lemmings/games.html.
Creating a game is a bit different from designing applications such as NetPaint and NetText. The largest adjustment you will have to overcome is implementing a graphics engine of sorts to handle all the drawing and animation that goes on in a typical game. Up to this point, you probably have been relying on Swing heavily, and making using of the update()/repaint() mechanism built in. The process Swing uses to draw is known as Passive Rendering, and while using Swing will still be more than fine for your basic User Interface in game, things will not go very smooth if you try to push Swing much further.
The process we will be using in the creation of Lemmings is known as Active Rendering. Here, instead of just "suggesting" to a component to draw, we are going to grab the buffer and draw directly on it. While there are numerous approaches to accomplishing this task, the easiest and more than likely the fastest is with the aid of a class known as BufferStrategy. Every frame, when your graphics engine is called upon, you will request a the Graphics2D buffer from the BufferStrategy, drawn on the Graphics2D object like you are accustomed, and then tell the BufferStrategy to go on and flip the buffer when you are done with all your drawing. This might sound daunting/confusing, but actually is quite more straight forward than swing, and works far more reliably.
Also, you want to avoid the overuse of Threading in a game, and unless you are integrating sound and networking, the rest of your game should probably run on one thread. All objects should be updated according to the time passed between each frame, rather than numerous timers or threads for each individual game object.
To see a general example of the set up of a BufferStrategy and the proper use of threading in relation to multiple objects, check out http://www.hydrous.net/~gt/2335/GraphicsExample.zip. Remember that you will probably want to use a Canvas instead of a Frame as in the example, as you can still use a Swing UI with an actively rendered Canvas embedded.
A few things you might want to remember/know when creating a game are as follows. Most of these come from experience, and some are fundamentals of Java and OOP.
Once you read the complete lab, you might be stumped on how to possibly implement maps easily in the game. As you may notice, Lemmings maps will be dealing with quite a bit of direct pixel manipulation. From the explosions to walkable areas, each pixel on the game screen might be touched individually at some point in time
One approach to the map would be with the aid of a couple of images, more specifically BufferedImages. A level can be created in any paint program, saved to a .png or .gif, and then used as the backdrop. A second image can also be created that will "mask" the level image. While the mask will never be displayed to the user, it will contain all the information on which portions of the map are walkable, which are not passable, and which pixels have been blown away etc.
The mask should be the same size of the level image, and can be thought of as going on top of the level image. The mask will be a "key" of sorts, as each pixel on the mask will correspond to the same pixel on the image. Instead of being used for display, the mask will have color values that indicate the status of each pixel on the map. For example, a Red Color (255, 0, 0) might represent an unwalkable area, while Blue (0, 0, 255) could represent a boundary. Whenever a Lemming moves in the game, you can check the mask to see if the move is valid, or if actions should be take to move to a valid pixel.
Since we have both the level and mask in images, accessing each specific pixel is quite easy and can be done with the help of the images Raster. A Raster contains all the pixel colors and the ability to set and check the color of any given pixel on the image. For example, lets say an explosion occurs at a point and has a radius of 5. You would then check the mask's Raster to see which pixels fall in that radius and have Color values that match pixels that can be blown up. After switching the relevant pixels on the mask, you then can change the level image to reflect the explosion in the mask. The methods you will primarily be concerned with for achieving this task will be the BufferedImage's getRaster() and the setPixel()/getPixel() methods of the Raster.
It is suggested that your program utilize three control threads for it's basic functions (hint: each of these should have a UML state diagram):
While we said that each Thread is a loop, in practice it MAY be best implemented in a method without a loop and just set a timer to call that method again later.
The main objective of the game is to get all of your Lemmings safely through the current level. You do this by giving special abilities to your Lemmings which allows them to navigate safely to the end (unless of course you have to blow up some of your Lemmings for the greater good of the group). Every level has the following properties related to it:
In this section, you will learn of the multiple abilities that a Lemming can have during the progression of the game. To give a Lemming a particular ability, you will have to do the following:
The default behavior (Walker) of all Lemmings is to pace back and forth. While in this state, a Lemming will walk as far as possible in the current direction it is facing, then it will turn around and repeat. Since Lemmings are not particularly smart creatures, they will walk off edges and will only be stopped by vertical obstacles. If a Lemming walks off an edge, one of several things may happen:
In addition to the default walking behavior, Lemmings have the following abilities:
![]() |
Digger - Burrows down vertically until it either reaches a non-diggable obstacle, in which case it stops, or it digs to the bottom of the current ground segment, which results in the digger (and all Lemmings following it) dropping down to the next piece of earth. If the Lemming burrows off the bottom of the screen, then he will die (as will subsequent Lemmings that fall into the hole made by the digger). |
![]() |
Blocker - Stands with arms outstretched to block the passage of other Lemmings. Once a Lemming becomes a blocker, the only way to get him to stop is to blow him up ( by causing Armageddon or by turning the Lemming into an exploder). |
![]() |
Exploder - This will cause the chosen Lemming to explode after a 5 second wait (during these 5 seconds, the Lemming will continue to operate in whichever role he had before), but the time remaining in the Lemming's life should appear above the poor creature. |
![]() |
Floater - If a Lemming is selected to have this ability, then the next time the Lemming falls off an edge, it will float slowly to the ground. Therefore, a Lemming can fall from any height without being harmed. Once a Lemming is given this ability, it will retain the skill until the current level is won (or lost) or until it dies. |
![]() |
Basher - Digs horizontally until it reaches a non-diggable obstacle or runs out of obstacle to dig through. The Lemming will only dig if he is directly in front (and facing) a suitable surface. If either of the previous conditions are not met, then the ability is wasted. |
![]() |
Miner - Digs diagonally down in the current direction the Lemming is facing. This ability has the same constraints as the Digger ability. |
![]() |
Climber - Climbs vertical surfaces. Once the Lemming has reached the top of the vertical surface, he will do one of the following:
|
![]() |
Bridger - Builds a bridge consisting of twelve bricks. Once the twelfth brick has been laid, he turns toward the camera for a moment. If you click on him again, he will lay another twelve bricks and so on. On the other hand if you choose not to click on him again, he becomes a walker again. The bridges constructed always span diagonally upward and in the direction the Lemming was facing. A Lemming will stop building a bridge if the bridge hits a solid object or if the lemming hits his head on something. |
![]() |
Jumper (Optional) - Causes the Lemming to jump in the direction they were currently walking. The lemming jumps both horizontally and vertically but covers a greater distance horizontally. The amount the lemming can jump is up to your implementation, but should be somewhat reasonable. |
| Hang glider (Optional) - Works like the floater. When a Lemming is chosen to be a hang glider, it behaves as a Walker until reaching at edge. Once it falls off, it falls at the same rate a Floater would, but keeps moving in the original direction of motion. Once designated a Floater, a Lemming keeps the ability until the end of the level or the end of its life, whichever comes first. |
A complete list of all original Lemmings 2 abilities can be found at http://www.utahdesign.com/lemmings/games.html.
While playing the game, you have the option to do any of the following:
Your game interface must contain the following items:
In addition to these game specific components, you need to have the following components:
You will need to construct a level set that requires you to use each type of the Lemming. Your levels should be larger than one screen size such that you can show your scrolling ability. There are several components to each level, which are:
All of your levels MUST be winnable, but complex enough to give some sort of challenge.
You will need to come up with some sort of way of representing a level on disk, such that you can load them whenever necessary. We recommend you use the rasterization method mentioned earlier.
The other major requirement for this project is to add networking functionality to your version of Lemmings! Don't worry, though, we are looking for you to implement the classic two player version of the game. The rules go a little something like this:
Each player (player 1 and 2) looks at a standard game screen. You need to have some method for each player to have an idea of how his opponent is doing. In other words, each player needs to see statistics on the player's number of Lemming's out, number in the Exit, number dead, etc.
There are some special rules, to this part of the lab, of course. Each player starts off each level with 40 lemmings. The number of lemmings that get saved by a player are added on to this initial value of lemmings. Play continues until both players fail to save any lemmings. The player who saves the most lemmings is the winner. To Nuke 'Em, both players must first click the button for this mass Lemming death to occur.
Other than these requirements, the game functions normally. Each player has his own set of skill icons. Either player can pause the game at any time. Lemmings head off, instinctively, toward the exit, after being dropped from the starting point.
If you do not implement the two-player mode / networking component the maximum score you can get on Phase 4 / In-Lab Demo is 80/100 and all extra credit is worth only half of its published value.
![]() |
Note |
|---|---|
| While you should pick a reasonable port number to use as the default, it should be possible for the user to easily change the port number being used. | |
While your team is able to explore many design options, the following program organization must be followed:
Your program must have three distinct units within it:
In practice it will look something like this:
+---------+ User Interactions +----------+ 2-Player +------------+
| GUI |<------------------>| Kernel |<----------->| Networking |
+---------+ Game Reactions +----------+ Updates +------------+
Your program must make non-trivial use of packages to properly organize your source files. One suggested method is:
edu.gatech.cs2335.lemmings.gui - The GUI front-end
edu.gatech.cs2335.lemmings.net - The networking components
edu.gatech.cs2335.lemmings.kernel - The game-play kernel
edu.gatech.cs2335.lemmings.junit - JUnit tests.
Your team will need to develop numerous UML diagrams to explain how your program will be organized and how it will work. The minimum set of diagrams your TA will need to see are:
Remember, these are the absolute minimum of the diagrams your TA expects to see, to get more than a "C" you will need to detail almost every aspect of your system.
![]() |
Warning |
|---|---|
The UML diagrams your team submits for Phase 1 will need to be full-and-complete (except for extra credit items). Any changes to your program (addition/subtraction/modification of classes, public/protected methods, etc.) will require significant explanation be submitted in writing as to why the change was needed. (Items added due to extra credit can be documented with "Changed due to extra credit." as the reason for change.) |
|
You do not need to account for using JUnit to test your program in your UML designs.
Your must create JUnit tests for all methods in the game-play "kernel" of your program, except the few methods that interact with the GUI or networking components.
To make life easier, you may test an accessor in conjunction with testing a modifier with one set of tests. For example:
public class Foo {
/* stuff */
public synchronized void setBar ( int bar ) {
this.bar = bar;
}
public synchronized int getBar () {
return this.bar;
}
}
public class TestFoo {
/* stuff */
/** Tests both getBar() and setBar(int). */
public void testGetBar () {
Foo tester = new Foo ();
tester.setBar ( 12345 );
Assert.assertEquals ( tester.getBar(), 12345 );
/* many more test cases */
}
}
You will be graded on the thoroughness of your testing... in almost all cases, fewer then three or four test cases for a method is totally unacceptable.
Please see Lab3 and the CS2335 Lecture Slides for more details on proper use of JUnit.
Your program must pass PMD, Checkstyle and Javadoc without producing any errors or warnings (the checks to use have are the same as were specified in Lab3.
![]() |
Warning |
|---|---|
Your program must pass PMD, Checkstyle and Javadoc without producing any errors or warnings. Significant point deductions will result if your program fails to pass all of the three cleanly. |
|
Your program must be packed into an executable JAR archive. The archive should contain everything needed for running your program and should be executable from the command prompt as follows (assume your archive is named "Lem.jar"):
% java -jar Lem.jar
Lab2 provides details on how to do this.
Your team must create an ant build file to be used for building and testing your program. Your build file must have the following targets:
jar - Creates an executable JAR of your program (this should be the default)
run - Runs the program
junit - Runs the JUnit tests for the program
build - Compiles your program
pmd - Runs PMD on all of your source files
checkstyle - Runs checkstyle on all of your source files
javadoc - Runs javadoc on all of your source files
Your program should not write any spurious output to the console (i.e. you will need to turn off your debugging messages in your submissions).
All "normal" exceptions must be caught and handled in an appropriate manner. An example of an appropriate manner would be having a pop-up window come up explaining (in "normal-people" English -- not "Java-speak") that there was an error. Exceptions that are outside of your control (e.g. running out of memory through no fault of your program) are not considered your responsibility.
Your whole program's GUI should be able to be seen (and fully playable) in a 800x600 window (with the level just scrolling left/right).
All Lemmings must be animated (this includes animation for those walking left, walking right, falling, digging, etc. for all the things a lemming can be doing).
We are requiring a minimum of three frames of animation per action.
You may find it easiest to pre-render the animation of the Lemmings.
Additionally, all Lemmings set to explode must have a count-down timer over their heads that counts down to the time when they will explode.
We know this is not a class on graphics and do not require extensive animation for the basic requirements in this lab. Simple animated stick-figures that have their arms/legs move is acceptable.
![]() |
Important |
|---|---|
19 March 2004 - Phase 1 Due In Lab (UML Designs)
2 April 2004 - Phase 2 Due on WebCT Before 08:00 (Partial Code + JUnit Tests)
16 April 2004 - Phase 3 Due on WebCT Before 08:00 (Complete Code)
23 April 2004 - Phase 4 Due on WebCT Before 08:00 / In-Lab Demo
|
|
![]() |
Warning |
|---|---|
| Phase 1 is due IN LAB, NO LATER THAN at 12:50. Unlike Lab6 you may NOT draw your UML diagrams by hand. All pages must have your team ID on them (e.g. "Ted 9" or "Joe 7"). | |
For Phase 1 you must submit a copy of all UML designs to your TA in lab. Please see Section 5.3. for more explanation of what diagrams are required.
Additionally your team must submit a completed P1_README.txt file. You should print out the file and staple it to the top of your UML diagrams. A good way of printing the file from within unix is with enscript, using the following command (substitute foo with the name of the printer you wish to print to):
% enscript -2rG -P foo P1_README.txt
For this phase your team must write most of the game-play kernel and enough of the GUI to start the game with a single level and show the Lemmings entering the level, falling, walking around, and changing direction when they hit a wall.
For this phase you must complete the following portions of your program:
![]() |
Note |
|---|---|
| Your code must compile cleanly and run. If your team gets a head-start on items not required for this phase (which is recommended) you should disable any items that cause your program not to compile/run (you may (comment-out section as required). | |
Your team must submit the following to WebCT in an archive (tar/gzip/jar/zip):
Everything should be working by now, except for the extra credit items. A few bugs remaining at this stage is ok (you can fix them over the next week), but they should not impact the overall functionality of the program. Sufficient levels should be included that show all of the tasks your lemmings can perform.
Your team must submit the following to WebCT in an archive (tar/gzip/jar/zip):
Phase 4: For this phase you will need to submit your finished project (extra credit options included) to WebCT as an archive (tar/gzip/jar/zip) with the following items:
![]() |
Important |
|---|---|
| Failure to submit Phase 4 to WebCT on time and without missing files will result in an AUTOMATIC ZERO for Phase 4/In-Lab Demo and will cancel-out any points assigned during the In-Lab Demo. | |
In-Lab Demo: This is "your time to shine." Your team will have 12 Minutes to show your TA the functionality of your program. It is essential to be prepared when your demo time begins because your TA will move onto the next team as soon as your 12 minutes is up.
Details on what to have prepared for your demo will be posted to the class newsgroup during the week prior to the demo.
Up to a total of 50 Extra Credit Points may be earned. All extra credit will be applied to the In-Lab Demo portion of your grade.
The following items are pre-approved for extra credit:
Your team may propose additional items for the TA's to consider for extra credit. All proposal for extra credit should be emailed to Adrian (aabraham@cc) by 23:59 on 31 March 2004, you must put "[CS2335] Extra Credit" in the subject line of the email. Items accepted for extra credit, and the point values of such will be posted to the newsgroup the following week.
A list of instructions to Lemmings can be found at: http://www.kallex.de/lemmings/misc/instructions.txt
You may find it helpful to play Lemmings to get a "feel" for how the game works before writing a clone for it. The following are a few of the known clones of the classic Lemmings (which is no longer available for purchase):
Use of these programs is AT YOUR OWN RISK and subject to their respective licensing agreements. CS2335 provides NO SUPPORT for their use.
Like the members of your team, not every CS2335 TA is an expert in everything, here is a quick list of who is an expert in what. (Note that you can still ask any TA, but these are the ones who will be best able to answer any specialized questions.)
TA | Expert In
--------+-----------------------------
Ted | Java Graphics
| Ant
--------+-----------------------------
Adrian | Extra Credit Options
| Sockets/Networking
| Threads/Synchronization
--------+-----------------------------
Joe | Lab Requirements
| Threads/Synchronization
| Using java.lang.reflect
--------+-----------------------------
Andrew | Ant
| JUnit
--------+-----------------------------
Ryan | Java Graphics eXpert
| Animation
--------+-----------------------------
Hemal | PMD/Checkstyle/Javadoc
| JUnit
| Eclipse/SWT
--------+-----------------------------