CSE142
Homework #4
Geometry Wars!
Electronic turn-in for part A due: Sunday, May 6, 10:00pm
Paper
receipt for part A due in class Monday, May 7.
Electronic turn-in for part B due: Sunday, May 13, 10:00pm
Paper
receipt for part B due in class Monday, May 14.
The Task
The Game
Part A details
Part B details
Extensions
Included Code The
Static Call Graph Your Writeup Partner
Declaration Guidelines, hints and help
Submission
Extras
Announcements
Rough Grading Guideline for Part A
Replacing a former MacroHard, Inc., employee, you've been hired on to a project
which is supposed to create an
educational game on geometry. At first, you have to spend time just
figuring out the project and the code already written. Then you join a
team to help finish the program. However, you and your teammate are
quickly bored with calculating the area of circles and squares. You decide
to sneak a little more excitement into the game. (fade to dream here)
You are the Quadrangles'
last hope. Being the last of the equilateral elite force, dodging and neutralizing sinister circles
left and right (not to mention up and down), you blast through the enemy ranks...
Ok, back to work.
Now that you know how to program using loops, and are starting to learn about pointers and arrays, you have most of the pieces you
need to create really interesting programs. In this assignment, you'll be
working (first alone and then with a teammate) on designing a computer game. The
game is based on RoboTron, a game where a player (or hero) is swarmed by enemies that must be neutralized.
This is also your first chance to deal with graphics! We're supplying you with a graphics package called
GP142. You should read the
GP142 User's Guide and look at how the GP142 functions are used in the existing code.
Apart from drawing, another important concept in GP142 is "Event-Driven Programming." Event-driven
programs operate by running through an "event loop" which receives various events, such as keyboard
input, mouse clicks, or ticks on a timer, and handles them as they come in. You will need to understand
this general structure in order to make sense of this program.
A great deal of code needed for the game is given. One of your first tasks
is to look at this code and understand it thoroughly! Only then
will it make sense to try to modify it.
Your job: with these tools in hand, finish the game.
The first part of the project should be done individually, as usual.
Before you turn in Part A, find a partner you can work with for Part B.
The game consists of a sequence of levels. At the start of a level, the hero is at the center of the screen,
surrounded by enemies. The enemies pursue the hero, trying to catch it.
Using the numeric keypad (with NumLock ON), the player controls the movement of the hero, trying to avoid contact with the
enemies. When the player presses the space bar or zero key, a projectile is fired in the direction the hero is facing.
If the projectile encounters an enemy, the enemy is neutralized.
The score is increased for every enemy neutralized. Once all the enemies on a level are neutralized, the player
advances to the next level.
Every time an enemy touches the hero, a life is deducted, and the level is restarted with however many enemies were left.
The game is over when the player dies and has no lives left.
As it is, the supplied code doesn't do anything very interesting.
Your first task is to change it enough to make a simplified version of
what the final game will be. The following is a list of things your
program should do for Part A. Some of these things are already in
place in the game. Some have to be implemented, and others
already have the code written but you need to figure out which
function call to make where.
Here is the list of required operational features for Part A.
The ones in red need to be finished by
you; the others are already working, and should remain working in the
version you turn in.
- The game should show a title screen at the beginning, including the game title, your
name, and some brief instructions
for the game.
- At the start of each level, clear the screen, place the hero in the middle of the screen, and
randomly place 1 enemy on the screen. (But, see the walkthrough for help with this part.)
- The hero should be controllable with the numeric keypad to go in
any of the eight cardinal directions (North, Northeast, East,
Southeast, South, Southwest, West, and Northwest).
- The enemy should chase the hero around the screen.
- No objects should be allowed to travel off the edge of the screen.
- Be able to fire a projectile
whenever there isn't a projectile already on the screen. Firing
projectiles should be controlled with a keyboard press (both the zero
key and the space key must work), with the projectiles traveling in the direction the
hero is facing.
- Each time the world is updated,
detect if the enemy is struck by a projectile. If it is, neutralize
the enemy. Neutralized enemies should disappear from the screen. For
each enemy neutralized, increase the player's score.
- When the player neutralizes the (single)
enemy, the game should pause and wait for a keystroke, then start the
next level.
- Each level should start by displaying a message (indicating that
the game is paused) and wait for a keypress to start the level.
- Detect if the hero is touched by
the enemy. If so, decrement the number of lives and restart the
level. If the hero runs out of lives (is hit by an enemy and has 0
lives remaining), end the game and show a "Game Over" screen.
You should complete and submit this part by the Part A deadline listed at the
top of this assignment! Also, you should turn in your static
call graph and writeup for Part A at that
time, as well as your partner declaration.
Although you will work with a partner for Part B, each individual student must
turn in all parts of Part A separately.
Although Part A might look a bit rough with a midterm coming up, the
internet has recently been flooded with copies of the HW#4A Walkthrough. That should make
things run a bit smoother.
For Part B, you and your team will build off of your code from Part A to finish the game.
You can start from either partner's code. You will do only one
electronic turn-in (with both of your names attached), and only one paper
turn-in (unless otherwise mentioned). Under normal circumstance, both
partners will get the same grade.
You will use your
newfound knowledge of arrays (including parallel arrays) to allow there to be multiple enemies and projectiles on the screen
at once. Also, this is your chance to really express yourself by adding in whatever extensions you
think would make the game more interesting!
Here are the requirements for Part B:
- The basic operational features from Part A remain, except as they need to be
modified for the points below.
- Replace the default enemy and player graphics with something more interesting. It doesn't matter
how you change them, so long as you add some new drawing elements. You are of course encouraged to
have some fun with this, and make something visually appealing.
- For each level, instead of having 1 enemy, have multiple enemies on the screen.
- The number of enemies should increase as you go up in levels, up to a certain maximum.
- When the player dies, the level should restart with a number of enemies on the screen equal to
however many enemies were left not neutralized when the player died.
- Start the next level only after all enemies have been neutralized.
- Give the player the ability to fire multiple shots in a row, rather than having to wait for one shot
to disappear before shooting the next one. This will require you to make arrays to hold projectile data,
rather than just single variables.
- To get full credit for the operational part of the program, your must have
the above features, plus 2 bells worth of extensions.
["Operational" refers to how the program operates. No matter
how many extensions you have, the program still has to follow expectations of
style and mechanics, have the written parts, etc. No amount of
extensions will make up for points lost on account of those types of things.]
The most fun part of this assignment is the opportunity to express yourself creatively by adding
whatever extensions you want to the game! These extensions are called "bells and whistles."
Different extensions have different values. A bell is equivalent to two whistles, so if you do one
extension that's worth a whistle, and a second that's worth a whistle, and
a third that's worth a bell, you've got two bells worth of credit.
For Part B, you're required to do 2 bells worth of extensions. If you want to do more, though, don't
stop just because you've got 2 bells! A certain amount of extra credit is available for going above and beyond
with added cool features, and the coolest programs will be demonstrated in front of the class in the
Homework 4 Hall of Fame!
Below is a list of some possible extensions, along with their values. There are many other
ways you could extend this game, and you are encouraged to come up with your own ideas! Just send a quick email
to your TA with a detailed description of what you've got in mind, and he or she will tell you how many
bells and whistles it would be worth.
WARNING: some of these extensions are very ambitious. Make sure to save a working version of your code
before you try to implement them! You don't want to mess up what you've already done just because you can't figure
out how to make some amazing new feature work.
| Put a starfield background or other nice effect behind the playing field.
|
| Allow the user to pause the game. Indicate visually somehow that the game is paused.
|
| Instead of showing a number for how many lives are left, draw little icons, one per life. Don't
let them obscure other screen elements!
|
| Make a flashy title screen for your game.
|
| Make enemies move faster as levels increase.
|
| Add difficulty levels (perhaps "Triangle", "Parabola", "Transfinite Hyperspatial Saddle Curve").
|
| Make some nice animated graphics for the hero or enemies. One bell per animated object, up to
a maximum of three.
|
| Create a little animation for when the enemies are neutralized.
|
| Instead of having boundaries on the map, have objects go off one side and come in on another.
|
| Create shootable stationary obstacles (like enemies that don't move).
|
| Have the number of points scored float up the screen from enemies after they've been neutralized.
|
| Wormholes that teleport objects from one location to another.
|
| Make the projectiles elongated (like an arrow for instance), such that they always point
in the direction they're traveling. See Llamatron
(at the very bottom of the page) for an example of this.
|
| The original RoboTron video game had two joysticks: one for player movement, and one for shot
direction. The player would shoot a constant stream of shots out in whatever direction the shot
joystick was pointing, and could move in another direction. This allowed much finer control, as well
as maneuvers such as strafing and a fighting retreat. Implement something similar, say by adding
a new set of control keys that just control shot direction. Another idea would be to use a system
like that of Llamatron, but that might be tough considering that you can't
really hold down keys in GP142.
|
| Let the enemies shoot projectiles at the player.
|
| Prevent enemies from overlapping each other.
|
| Gravity generators that "attract" objects towards them.
|
| Create some sort of powerups the player can pick up. Make them worth points, or give the player
special abilities. For example: speed up, temporary invincibility, fire shots in all directions, etc.
|
| Add walls that block movement and projectiles.
|
| Create multiple enemy types, with different behavior.
|
| Make the enemies try to dodge bullets.
|
| Create different weapons for the hero to fire. There should be a few, with various interesting
effects, to get a full 2 bells' worth of credit for this one.
|
| Asteroid-type enemies that break into smaller parts.
|
| Create a "droid" that helps the player by running around and shooting enemies without being controlled by the player.
|
| Make the game world be bigger than what can be shown on the screen at once. This would involve scrolling
through the larger world as the player moves around.
|
????
| Anything you can think of! Just e-mail your TA with your extension suggestion,
and ask him or her how much that extension will be worth.
|
There is a lot of code provided for this project, but don't panic! For the most part, you only
need to change the code in hw4.c. You can think of the other files as being like libraries that
provide additional functions without your having to implement them or worry about how they work internally.
The only times you'll have to change what's in the other files is for Part B when you're changing the drawing
functions and adding bells and whistles.
You are free to change any files you want, though, except the GP142 files!
You are given unfinished code separated into several files:
- hw4.c
- This is the main file, with all the code you'll need to change for your program. It will need to call
functions that are defined in other files.
- tron.h
- This is a header file with various function prototypes and symbolic constants that are used
by more than one other file.
- tronDraw.c
- This file contains the code for drawing various screen elements. You aren't required to
change anything in here, but if you want to change any of the game's graphics this is where
it will need to be done. Note that this is the only file that makes any calls to the GP142
drawing functions.
- tronMove.c
- This file contains a bunch of functions related to movement of objects in the game.
- GP142.c, GP142.h, GP142LIB.h
- These files comprise the GP142 graphics package. They must be in the project, but you should
not need to even look at the code in them. Definitely do not modify them!
Download the self-extracting archive to get started (or the plain zip file).
Because this file has multiple .c and .h files, you cannot create and run
a "default project" as you might have done for the previous homeworks.
The best thing is to use the project workspace already supplied (.dsw
file). If you don't want to do that, there are two crucial things to know
about when you create your own MSVC project.
- The project type must be Win32 Application. If you select the wrong
type, the programs might compile, but you will get very strange linker
errors (probably something about main and Win16, etc.)
- You must insert all of the required .c files into the project (hw4.c, tron.h, tronDraw.c, and
tronMove.c, plus gp142.c), and make the corresponding .h files available
to the compiler. Without the .h files, the .c files will not
compile. Without the .c files, you will get linker errors.
To get an idea of what your finished project should look like, have a look at the sample executables for
Part A and Part B. Note that the sample executable
for Part B has no extensions to it, but yours should!
It's your responsibility to understand all of the code in hw4.c and to understand
how and when to call each function in tronDraw.c and tronMove.c. Part A only requires you to change hw4.c,
and most of the changes (but not all) for Part B will be in hw4.c, as well.
Be sure to read all of the comments describing each function given.
Also, because there is so much existing code for you to work with, for this assignment you are
required to write code using the same styles for variable names, bracing, indentation, etc. as what's
already there. This is as opposed to changing the existing code to suit your preference, which just
doesn't make sense for a project of this size.
You also need to become familiar with GP142.
Read the
GP142 User's Guide. Don't expect to understand everything
the first time you read it. As you work with the program,
it will make more and more sense.
Do not modify any of the GP142 files (GP142.c, GP142.h, GP142LIB.h).
Because this is the largest amount of code you have worked with so far, part of your
Part A writeup involves
creating a a static call graph, which displays the relationships between the
various parts of your program. Your turnin for Part A is to include a static call graph based on the
supplied code as modified by you. You used a static call graph in Homework 3
and on some lecture slides, but here's a refresher and some tips:
A static call graph is a diagram with one box for each function in the program. Put the name of each function in a box.
For each function B called by another function A, draw an arrow from A's box to B. For example, if main calls drawScreen,
draw an arrow from main to drawScreen. It's best to organize the boxes in a sort of hierarchical, tree-like
structure, rather than laying everything out at random on the page. Hint:
start with a large piece of paper, and put main at the top.
There
should be one box for each function defined or called in hw4.c.
Functions in tron.h, tronDraw.c, tronMove.c, GP142 or C library functions which are called from
those files hw4.c should be
included. However, it is not necessary for you to look inside any of those
files.
There is no electronic turnin for the call graph, just turn it in stapled to your printed receipt. Make sure to put your
name and section on the call graph, even though it's stapled to your receipt.
In addition to the call graph, you will be submitting a writeup (as usual) for both parts of this assignment.
We have supplied starter files for
Part A
and Part B
that include the questions below. As always, include the following standard info:
- Your full name
- Your section
- Approximately how many hours you spent on the assignment
- Acknowledgment of any help you received on the assignment from any source
other than the lectures/sections, the staff, or the course textbook. (Note
that acknowledging activities which constitute cheating does not stop them
from being cheating!)
For this assignment, we also request 4 sets of questions. The sets cover
Pre and Post questions for both Parts A and B. The Part A questions are due
with Part A and the Part B questions are due with Part B.
Don't write more than a couple of sentences to answer any one of these questions!
Pre-Part A questions:
- What is GP142? What does it allow you to do?
- Which of the required features are not already implemented? What function bodies will you have to change in order to implement them?
Post-Part A questions:
- If we changed this homework so that you needed 3
enemies instead of 1, how much more difficult would the
program be to write without using arrays?
- Did you change any of the code in the files other than hw4.c? If so, why and
in what ways? If not, why was it not necessary to do so? What do you think of the practice
of breaking code up into several files like that?
- How does the program detect whether the enemy has been shot? Which part(s) of the code are
responsible for making this determination?
- What extensions do you plan on implementing for Part B?
- Partner Declaration: Will you be working with a partner for Part B?
Answer yes or no. If the answer is yes, please give the partner's name, student ID number, email address, and section.
Notes:
- you cannot work with a partner unless you make this partner
declaration when you turn in Part A.
- You cannot change your partner, once declared.
- You may not choose later to work alone, once you have declared a
partner.
- Homework 5 will also have a partner, and you will have to choose a
different partner.
Pre-Part B questions:
- What variables in the main function of Part A should now be declared as arrays?
- Will you need to change every function to handle arrays, or is there some way you can have
lower-level functions work in Part B without modification? Which functions might you be able to
leave as they are?
Post-Part B questions:
- What did you do for your extensions? Please tell use exactly
which extensions should count as your two required bells and also
what extensions you have implemented for extra credit.
- What are the benefits of using parallel arrays? What are the drawbacks? Can you think
of a better system that would get the same benefits without those drawbacks? What would it be like?
- What's your high score?
- What's the most insightful or interesting question you thought of,
asked, or heard asked about this assignment? If it was a question you
heard, make sure you attribute the source! Explain briefly why this was such a good question and
what you think the (an?) answer is.
- What did you enjoy about this assignment? What did you hate? Could
we have done anything to make it better (either the assignment itself
or the way we handled handing it out, clarifying it, or turnin
procedure)?
Coding style (following The Way) is vitally important for this
assignment and all others. We will generally grade your code for three things:
functionality (does it work?), style (is it readable, maintainable, and
changeable?), and robustness (does it work well?). So, style will factor in
heavily. Moreover, if your code does not work perfectly or is not perfectly
robust, you will lose fewer points if we can understand the problem's cause...
and good style will help us to read your code enormously.
The following advice should help greatly with your work. Some of it will
seem vaguely familiar.
- You'll want to pay very close attention to types when you're passing pointers around. Suppose you have
functions with the following three prototypes:
void func1(int foo);
void func2(int *bar);
void func3(int *baz);
Now, suppose func1 calls func2, and wants func2 to be able to access the value of the variable foo.
Because func2 expects a parameter of type int *, the function call should look like this:
func2(&foo);
Now, what if func2 wants to call func3, and allow it to access that same data (the value pointed to by bar)?
Because bar is already of type int *, you don't want to use the & operator. Instead, the function call should
look like this:
func3(bar);
For either func2 or func3 to access the data, they should use the * operator because
they are dealing with a pointer. For example, in func3:
*baz = 10;
- Don't hold down keys in GP142 programs -- it makes the program freeze up. To move or shoot in this
program, you only have to hit the key once.
- When moving around, you can hit '5' to stop. If you hit '5' again, you'll keep going in the
same direction. Think about what this means in terms of how the player's facing is stored,
and have a look at the code that handles it. Do you find it clever? Can you think of a better way?
- One bug you want to be careful about in part B is letting a single projectile neutralize
more than one enemy. Think about how to avoid this, especially when enemies are all bunched
up together!
- Make use of the class newsgroup to discuss any questions you have about the project.
However, make sure that you are very familiar with the academic misconduct guidelines!
Don't post code from your project to the group!
- Start early. Despite the fact that it improves your life immensely, so
many people ignore this advice. It always pays to get an early start.
- Read these instructions completely and carefully. Very good students do sometimes lose
points simply because they didn't read the directions. This is not just a matter of us being
picky; real life programmers have to be very careful about sticking to the specification provided!
Read the instructions completely before beginning to work, and again just
before you turn in.
- Before writing a single line of code, plan your solution on paper. Try
thinking about what you would do to perform the computations yourself.
- Develop and test the program a bit at a time. Don't try
to write the whole program and test it all at once. Instead, try getting a
small part working. Then, test and add more pieces bit by bit until the whole
job is done.
- Before turning in your work, test it thoroughly.
- If you get stuck on a bug, remember to use the
Bug Triage Checklist to get you unstuck! Don't just spin your wheels helplessly or
randomly move code around!
- When it comes to grading, there's nothing better than a happy TA. Make
your TA a happy TA: Your code should be neat and readable, with sensible
variable names.
- Start right now!
Here is the part
B turnin. It requires submission of hw4.c,
tron.h, tronDraw.c, tronMove.c, and your
readme.txt file.
Nothing better to do?
Finished reading
the complete works of Shakespeare, memorized
10,000 digits of PI,
completed your award-winning thesis on biochemical reactions in the
spleen,
ended famine in no less than 3 third world countries,
and feeling antsy for more?
First, turn in a working version of your code. Then, try to duplicate this!
Finished with the assignment and made it look like Llamatron?
Hmm.. Let's see... there are still more digits of PI (you never know who you will impress)!