Homework 9: Make Your Own Game

xkcd game pointers
Component Due Date
Project proposal document Friday, November 22 at 11:59 AM (NOON!)
Project code and README document Monday, December 9
Game demo to your TA Reading Days (December 10-11)

No late submissions can be accepted for this assignment!

Assignment Overview

In this assignment, you will create your own game using the Java Swing GUI framework. Though you will choose the game and implement it from scratch, your implementation must be well designed and must integrate several programming concepts from this course. Use this project as a chance to show off everything you’ve learned and to build a large-scale application of your own design. You will demo your game and explain your design to one of your TAs in a one-on-one session during reading days.

Have fun doing this assignment! This has historically been students’ favorite project of CIS 120, and you are more than welcome to go a little overboard if you choose. :-) Many students invent a totally new game as part of this project, and these are always a ton of fun to show off.

Project Requirements

You are completely free to either choose to implement an existing game or to come up with your own, unique, super-duper awesome game.

No matter what kind of game you build, it must meet the following criteria:

  • Project Proposal [8%]. This document will lay out your plan for implementing your game. See below for more details.

  • README.txt [4%]. You will submit another document along with your code, detailing your game and any changes you needed to make to your design. Make sure it's in line with your actual game. Your README should include the four concepts that you implemented. We have also provide a blank README for you to fill out in the project files.

  • Instructions Window [5%]

    Your game must provide easy-to-find instructions, including:
    • A brief explanation of the game you implemented.
    • An explanation of how to play the game, including how the keyboard and/or mouse should be used.
    • This is also a great place to boast about anything cool you’ve implemented that you want to make sure we don’t miss.

    In their excitement of creating a new game, some students overlook this part of the rubric. However it is a really important component of your project, especially when it comes to grading. Don’t miss out on an easy 5 points!

  • Mouse and/or Keyboard Controls [5%]. You will need to implement mouse and/or keyboard game controls as appropriate for your game. The sample game that we've provided demonstrates simple keyboard control using the arrow keys, but you will probably need to make this more sophisticated. Try to make the player’s experience a good one.

  • Game State [9%]. The game should have a way of displaying the player’s status (which could include running score, number of lives, time elapsed, etc.) as appropriate to the game. Those values should be incremented, decremented, or manipulated appropriately as the game progresses. There should be a detectable end state to your game. (This could include winning, losing, running out of time, etc.)

  • Implementation [5%]. This category depends on the game you choose to implement and whether or not it works correctly.

  • Design Concepts [16% per concept, 64% in all]. The point of the game project is to synthesize all the concepts that we’ve learned over the semester and apply them in the context of game design. In order to facilitate that, we have compiled a list of core concepts that we've covered throughout the semester. We’ve also made a list of additional concepts that are particularly relevant for game design that you may also choose to use. Some of these are more advanced topics that we have not covered in class.

    For your game, you must implement four of these design concepts. Just to be clear, you have to choose four distinct concepts; we will not accept any double counting. See below for more details.

Your code must compile for you to recieve more than 12% on this assignment! Do not wait until the last minute to make huge changes to your code, and make sure you save working versions as you progress through your implementation.

You must use Java Swing for this assignment. Failure to do so will result in you only getting points for your proposal (8%)

Part 1: Project Proposal

If you took CIS 110 and made a game, you cannot use that same game for the CIS 120 game project. Additionally, you cannot reuse code from past homework assignments if that code is instrumental to the concepts that your game implements. For example, you cannot simply copy and paste hw08 code to implement a file IO system in your game and receive credit for implementing the IO concept.

A component of your grade for this assignment will come from a project proposal which you will submit in advance of the project deadline. This is the only (required) way to get feedback on your proposal before you start implementing your game. It is due early in the process, and you will be uploading it on Gradescope. You can view the skeleton proposal document here. Please copy the document from that link, fill it in, and save it as a pdf. You must use this skeleton proposal document (do not adjust the formatting!). Overall, you will use the proposal to document your initial design process and plan your implementation.

Your proposal will include a brief description of how you will use four distinct design concepts in your game.

Your game should demonstrate that you have a practical understanding of the core concepts you learned this semester. To do this, think about a few of games you might want to implement, and break each of them down into the concepts they demonstrate.

If you can’t think of four, don’t give up! Ask on Piazza or in office hours how you might extract more concepts from the original game you’ve chosen, or what features you might be able to add.

You can definitely include more than four concepts in your proposal (and will get feedback on all of them!), but you will only be graded for four concepts when you submit your completed game

It’s important to choose the game that you feel would allow you to focus on demonstrating your knowledge. A poorly designed implementation of a complex game is worse than than a well-done implementation of a simpler game.

Example Proposal

Here is an example game proposal for the game Tic Tac Toe. Note that, because we have used it as an example, you are not allowed to choose Tic Tac Toe for your game. Notice that we did not edit the formatting and we only picked four design concepts!

Additional Proposal Guidelines

Here are some tips/suggestions put together by some of the TAs on what we may be looking for in your proposal. It may also help you identify what game you want to use. For some of the concepts, we’ve also put some common use cases/games and common mistakes.

Submission instructions for the Project proposal

Your project proposal is due on November 22 at 11:59 AM (i.e., noon!)

Submitting your proposal late will result in no points for the proposal, but you will still get feedback.

  1. Make a copy of the game proposal in Google Docs. (Choose "File > Make a copy".)
  2. Edit the document to reflect your plan. Do not change the sizes of the text boxes when editing of the document.
  3. Download the proposal as a PDF file. (Choose "File > Download as > PDF Document")
  4. Upload the PDF to the CIS 120 course on the Gradescope site.

Design Concepts

Decompose your game design so that it makes use of four of the following concepts. Justify your choices in the game proposal document.

Your four design concepts must be used for different aspects of the game (i.e. if you are using I/O for high scores and use a collection while reading a file; you cannot count Collections as a concept)

Core Concepts from CIS 120

These concepts have been covered in class or in past homework assignments. You should feel comfortable using any of them in your game design.

  • Appropriately modeling state using 2-D arrays

    The internal game state of most grid or board based games are best modeled by a 2-D array which directly represents the rows and columns of the grid/board. It is important to take into consideration whether or not a 2-D array is necessary to model your state and what data it should store. If you choose to use this concept, refer to what you learned in homework 06 (Pennstagram) for a better understanding of how to properly use 2-D arrays.

    Your use of arrays must be sufficiently interesting. 2D tic-tac-toe with brute-force search is not interesting.
  • Appropriately modeling state using collections.

    Many games will need to use collections or maps to model their state. You won’t receive credit just for using a collection; what matters is choosing the appropriate data structure for the piece of state you are modeling. The data structure you choose should make it easy to manipulate and retrieve the game state. Be sure that you can justify why your choice is a good one. Additionally, while we do not grade style for this assignment, we do require that your static types be interfaces.

  • You are allowed to use both of the concepts described above. However, you are not allowed to (and should not want to) model the same state with both a 2-D array and a collection.

    For both of the above concepts, you should be making sure that your state is properly encapsulated.

  • File I/O: using I/O to parse a novel file format.

    You might choose to design your own text or binary file format and have your game read and write files using that format. Note that this format must be one of your own design and it must involve at least two pieces of state. If Java already has a library for parsing this format, then this is not an appropriate use of this concept. You may write your own library for an existing format, but using a library provided by Java will earn 0 points.

    A common use of I/O is enabling persistent state between runs of your game; for example, you might write high scores out to a file and read them back in each time your game starts. I/O can also be used to create arbitrary levels, where a text format specifies features of the level (rather than hard-coding levels into your game).

    Recall that HW08’s FileCorrector “corrections file” format included several pieces of information on each line of input. Also, the FileCorrector needed to be resilient and error-tolerant. If you use IO in your game, you must handle all edge cases and ensure your game does not crash due to bad or poorly formatted input.

    To be eligible for full points for the I/O concept, your I/O must incorporate both input and output - that is, you must use both a Reader and Writer.

    In addition, your file I/O format shouldn't be the same as the comma separated format from HW8.

    For example: if you are storing “levels” in txt files that can be loaded from a file, you must also support functionality for writing out to a file - for example, you can include a “save” button that writes out the current game state, and another button, “load” that restores the most recently saved game.

    If you’re using I/O to implement high scores, there are a number of requirements: 1) The displayed scores must be in sorted order (highest score to lowest score), 2) you should display at minimum 3 scores (when 3 scores are available). 3) Your high scores must have some extra data associated with them. E.g. (First Name, Last Name, age, Score)

    If you use a collection in your I/O concept (e.g. a list to store all of the high scores that you read), you cannot count this use of collections for the "Appropriately modeling state using collections" concept

  • Using inheritance/subtyping for dynamic dispatch.

    You can use Java’s subtyping features to group and organize different entities in your game. We require that you justify why you decided to design your classes and interfaces in this particular hierarchy, and that your justification is reasonable. We will not accept simply the creation of an interface and a single class that implements it.

    Note that there should be a natural subtyping relationship being modeled here (i.e. it would make sense for one component to be a subclass of another). The relationship should not be so simple that it could easily be represented by altering a field or passing a different argument to a constructor (like the color or speed of a piece).

    Consider the two following implementations of tower defense classes:

    • Invalid: Your different defenders have attributes such as health, speed, and size. Notice that these are simply fields and do not require different implementation of methods.
    • Valid: Your different defenders attack in different ways. Some attack by weakening all the enemies at once, others attack by only targeting the weakest enemy until it is dead. This requires different implementation of an attack method for each type of defender and would make sense for this assignment.
    Your new interface/abstract class (e.g. Defender) that will be a supertype to the concrete classes you are implementing (e.g. AttackAllDefender, AttackWeakestDefender) must have a new method that your subtypes implement differently (e.g. a defend() method with a different implementation per Defender).
    You are not allowed to use GameObj alone as the basis of your inheritance. If you do this, you will receive no points. If you need it in your inheritance tree, create an abstract class that extends or interface that complements GameObj with significant changes and use this instead.
  • Using JUnit on a testable component of your game.

    This concept consists of having a well-designed game containing an encapsulated model that functions independently of the GUI, as well as JUnit tests for this model. There should be a consistent interface for the model, which is updated by calling methods. Your code must, by design, be unit-testable.

    An example of a testable model is the chat homework assignment, where the ServerModel class stores the state but does not deal with any low-level components of the server’s networking and does not deal with any high-level components of the user interface.

    The unit tests that you write should be testing some aspect of your game's model, not the game's GUI aspect (e.g. you should not be testing that the user pressing SPACE will make the player jump).
  • Implementing recursive algorithms.

    There are several useful recursive algorithms you might wish to implement, including depth-first search of a graph, traversing a tree structure, or finding a path through a maze. You should consider whether a recursive implementation is strictly necessary for this algorithm to work

  • A novel linked or recursive data structure.

    Some games might have states that aren’t easily modeled by an existing collection. For instance, you might have a maze or a network of rooms connected by corridors, and each node should know the others it is adjacent to. You might also find that a tree-like structure could be helpful for modeling a particular problem. Whatever you decide, your implementation must be a data structure not already available to you in the collections library.

  • Complex game logic

    The only game currently approved for this concept is chess. If you are considering this concept for a game that is not chess, you must get approval from a TA or professor.

    In the past, chess has been challenging for students to fully implement because of difficulties in core game logic. In order for your game of chess to get full credit for this concept, your game must implement the features of check, checkmate, en passant, and castling in addition to normal game features (e.g. moving pieces, capturing pieces, preventing invalid movement of pieces, etc.). For example, this concept includes making sure that a user’s piece should not be able to move into a state that results in check, and a user that is checked must be forced to resolve the check. Put simply, your game of chess must include all of the standard features expected in chess.

    If you do not implement these features of chess or plan to implement these features but change your mind, you can still get full points by implementing four other concepts.

Advanced Topics

You may choose only one advanced topic for your game project

If you have an idea for a more advanced topic, please consult with your TA. You may only be approved for up to 1 advanced topic. Examples of possible advanced topics are as follows:

  • Collisions (beyond simple bounding boxes or circles)
  • 3D Graphics
  • Network I/O
  • Concurrency
  • AI

If you believe one of these topics is simpler than the core topics listed, your TA will likely not approve of the advanced topic you have chosen because it is not complex enough. The purpose of allowing credit for these advanced topics is to allow students to go above and beyond in the course and learn on their own. Please note that there will be very little TA assistance available with these topics due to their advanced nature and the expectations are high, so please take the time to fully consider tackling these topics.

Choosing which Design Concepts to Implement

When choosing which concepts to implement, we advise you not to get too ambitious. Again, it is much better to implement a simpler game well than to attempt a more complex game and execute it poorly. The point of this assignment is to demonstrate your understanding of the concepts taught in this course, not just to show the most difficult, complex thing you can make.

Feel free to post on Piazza if you have an idea for an advanced topic that no one else has suggested before. It is especially important that you get feedback on these (an idea that sounds like an advanced topic doesn't necessarily have to be advanced).

If you do post to Piazza, please make such posts public so that we do not have to field repeat suggestions.

If you plan on posting to Piazza to ask about your own idea for an advanced topic, you must do so before the proposal is due, and you cannot choose to use an advanced topic that has not been approved.

Keep in mind that at least three of the design concepts you use must be core concepts from CIS 120; there are no exceptions to this.

Only a maximum of 100% may be earned for this project. Even if you implement more concepts than necessary, they cannot bring your total to over 100%, nor can they compensate for other missing criteria. For example, if you fail to provide instructions, the highest score you can get is 95%, even if you implement twelve different core concepts.

Part 2: Game Implementation

A Note about External Resources

For this project it is not necessary to use any external resources, such as images or third-party code libraries. However, you are welcome to use them, subject to the following conditions:

  • You may not read, follow along with, or copy anything from a tutorial that relates to any of your implementations for core concepts. We will be very strict in enforcing this policy because we want to make sure that everything we are grading is your work. This does not include explanations of algorithms, but as mentioned above, you are still not allowed to view any code for them. If you are implementing something external to the core concepts we are grading, then you are allowed to view a tutorial that explains concepts, but you must cite your sources in your README.txt.

  • Any library code you use must work on Eclipse. (This rules out some platform-specific libraries or libraries that require the use of non-standard hardware.)

  • Any library code that you use cannot itself count toward any of the graded components of your project (e.g. if you use a Java library for animations, you may not count the implementation of animations as a design concept).

  • If you have questions about whether your use of a third-party resource is allowed, consult the course staff for help.

  • For resources like images you should be fine using whatever you like, since this is a not-for profit educational project. However, if you plan to distribute your game more widely, you should keep in mind the rules about fair use of copyrighted material.

Starter Code: The Mushroom of Doom

It would be cruel to ask you to write a game completely from scratch; even experienced Swing programmers generally start new programs by modifying existing code or by using a tool to automatically generate some starter code. So, we’ve provided you with a very simple example game that you can use as a starting point if you like. (Your game might quickly outgrow the provided structure, so you should create new files and reorganize things as necessary.)

mushroom of doom

Our sample game is rather silly, really super cool. You can move the black square using the arrow keys. Then, there is this mushroom. If your black square touches it you die. Of course, you win the game by catching the golden snitch. Try it out by downloading the starter files and running the Game class. You’ll need to make sure that the image file poison.png is in the files subdirectory before you play the game.

The game doesn’t do anything fancy like allow multiple players or keep score, but even such a simple program already demonstrates a lot of the key concepts you will need to make your own game. You should read all of the code provided before beginning to write your own game, though you are not required to use any of this code in your own game.

Here’s an overview of each of the provided files:

  • Game.java: This file contains a class with a simple main method to run the game. It implements Runnable, in particular it provides a run method. This method sets up a basic window with a Reset button, a Status line, and a GameCourt.
  • GameCourt.java: This is where the real action happens. The GameCourt is a JComponent on which the current game is displayed. It handles user keypresses, and sets up a Timer to generate an event every 35 milliseconds so that the screen can be redrawn. It also has a Square, the Poison mushroom, and a Circle (i.e. the snitch); it updates all of them before redrawing the screen.
  • GameObj.java: GameObj is the base abstract class which collects behavior common to the different objects in the game. A GameObj is a rectangular object which has a position, a size, a velocity and bounds. Game objects can be moved, drawn, and bounced based on collisions with walls and other GameObjs. This game creates three subclasses of GameObj:
    • Poison.java: A Poison is a GameObj that represents a poisonous mushroom. It doesn’t move, but demonstrates how to display game objects using images.
    • Square.java: A Square is a GameObj which looks like a square. It is controlled by the keyboard in GameCourt.
    • Circle.java: A Circle is a moving GameObj which is displayed as a circle and bounces off of the walls and the Poison.

The intersect code in GameObj.java is only accurate for squares. Something a little more clever is required to accurately detect collisions between more interesting shapes.

Implementing Your Game

From here on out, you’re on your own! Your game project will be graded partly on a set of implementation criteria and partly on your explanation of the implementation during the demo session (see grading).

Backing Up Your Code

For this assignment, we strongly recommend that you make snapshots of your code periodically. You might want to consider learning and using a source control system such as Git.

At the very least, periodically make backups of your project by saving your code under a new file name

Using Libraries

You can use all of the standard Java libraries without any doing anything special. However, you are welcome to use external (3rd-party) libraries packaged as .jar files. To use such libraries in the files foo.jar and bar.jar:

  1. place foo.jar and bar.jar in the project folder at the top level (i.e. at the same level as Makefile)
  2. edit the Makefile so that the JARS definition includes a (colon-separated) list of the jar files you need, e.g.
    JARS := foo.jar:bar.jar

Now, compiling your code should include the jar files as libraries.

Submitting Your Game

You must submit a single archive called hw09-submit(time).zip. The most important requirement is that it must include a Game class (it has to actually be named Game) with a main method:

public static void main(String[] args) 

This Game class must be in the default package so that we know where to look for it.

Your hw09-submit(time).zip must also include a text file called README.txt that gives an overview of your game implementation and the four concepts you implemented. It should briefly describe all of the classes that make up your game as well as give any special instructions (like additional libraries, etc.). We will look at this file first when grading your assignment.

The archive must contain all your sources. If your project uses additional libraries, the archive must also contain the requisite .jar files at the top level folder. If your project needs data to run—game level information, images, sounds, etc.—the archive must contain these as well: put them in the files directory.

If you are using Eclipse
  • Alternative 1 - Zip your files from Eclipse using the instructions below.
  • Follow these instructions to create and upload hw09-submit.zip:

    • Right click on project, select Export...
    • Expand General, select Archive File
    • Browse... -> Save as "hw09-submit" in Desktop/Documents/Downloads
    • Choose the required files (refer to the note below)
    • Select "Save in zip format"
    • Finish
    • Go to submission site, find file in Desktop/Documents/Downloads and then upload

  • Alternative 2 - Copy-Paste your code in Codio and zip from there.
  • The zip file you submit should have the structure shown below. If you are using Codio, the "Zip Project" menu item we provide should create it:

              README.txt
              Makefile         // this is just copied from Codio
              *.jar            // any library jar files your game needs
              src/Game.java    // the Game class containing the main method
              src/*.java       // any other source code you create
                                  (or src/*/*.java if you use packages)
              test/*.java      // any test code you create
              files/*          // any image, data, or other files you need
                                  (or files/*/*)
              

    If you are using JUnit testing in your code, you will need to include a .jar file for the JUnit libraries. (We installed one for you in the codio account.)

    The submission page attempts to compile your code and checks for the main method. It will tell you if this compilation fails. The most common cause is forgetting to include a file.

    For some projects that depend on external libraries, the submission tool might still complain, even if you are sure you included every file and they all compile. If this happens, it’s probably because the submission server isn’t able to include the external libraries. Please email your recitation TAs so they are aware your submission may not have compiled on the server.

    There is no penalty for extra submissions on this assignment, so get started early and submit often!

    To run your game, we will execute the main method in your game class with the below command. Your game will be run on the lab Linux machines in Moore 100A. If your code does not compile you will not receive any credit.

    Demonstrating your Game

    Your game will be graded during a demo session with a TA. We will play the game so you can show us all of your features and we can look for bugs. We will expect you to walk us through your Java classes and explain how everything works during the demo session. Be prepared for questions about your implementation.

    You must schedule a demo session with a TA (they will send you an email to arrange a demo). Sessions will be available throughout reading days. Each demo slot will about 15 minutes long. Not showing up for your Game demo will result in a -20pt deduction!

    Your TA will email you with more information about how to schedule your demo session closer to the due date.