© Kathi Fisler, 2007-8
Your job is to write a simple interactive game in which the player drops water from a plane onto fires on the ground; the goal of the game is to put out all of the fires by dropping enough water on them. A sample appears to the right. The plane is always moving across the screen (independent of user input). The player can change the direction of the plane by pressing the left and right arrow keys. The player can also drop water from the plane by pressing the down arrow key. Each fire has an intensity: when a drop of water hits a fire, the intensity decreases. If a fire burns without water hitting it, its intensity increases. A fire is extinguished (and disappears) when its intensity reaches zero. The game ends when all of the fires have been extinguished. You will build this game using the same world.ss teachpack. Work in the "Beginner with List Abbreviations" language level. |
To write this game, you will need to provide at least the following:
A data definition for the "world", which is a single data structure containing all of the information that makes up the current configuration of the game (such as the plane, fires, and water drops and their constituent information). Include all data definitions needed to write your overall world data definition. Do not assume the same number of fires for every use of the game.
A function draw-world
that consumes a world datum
(from the previous item) and produces an image of that world (using
place-image
and empty-scene
as shown in the
world.ss documentation). The place-image
function
produces a scene, so you can nest calls to place-image
to
put multiple objects into a single scene.
A function process-keys
that consumes a world
datum and a key-event (symbol) and produces a new world datum reflecting
changes in the world based on keys pressed.
A function update-world
that consumes a world and
produces a world reflecting what happens when no key is pressed (ie,
the plane continues to move, the water continues to fall, etc).
A function game-over?
that consumes a world and
produces a boolean indicating whether the animation should stop.
Once you have these functions, you will run your game using the commands:
(big-bang WIDTH HEIGHT (/ 1.0 28) INITWORLD) (on-redraw draw-world) (on-key-event process-keys) (on-tick-event update-world) (stop-when game-over?)where WIDTH, HEIGHT, and INITWORLD are constants you define for the size of the game window and the initial configuration of the game. You may omit any of these lines if you haven't yet written the corresponding functions (like
game-over?
)
The exercises in the next section break down the above steps to guide you through the implementation. For more of a challenge, figure these steps out for yourself (see the hints and tips section following the broken-down steps).
We do not expect you will finish the whole game in this lab setting. The goal here is for you to get experience working with lists nested within structures, and more experience with world.ss. Hopefully, everyone will get about halfway through this during lab (question 5 on the broken-down part).
Data definitions, examples and templates: Define the world to be a structure containing a plane, a list of fires, and a list of water drops. The plane should have a location (posn) and direction of travel. Fires have a location (posn) and an intensity level (number). Water drops have a location. Write out examples of data and templates for your data definitions.
Draw the plane: Write a draw-world
function
that draws the plane, but ignores the water drops and fires.
Animate the plane: Write the process-keys
functions describe above to move the plane by user key presses. Write
an update-world
function to move the plane in its current
direction when no key is pressed. Your test cases may assume that the
lists of fires and water drops are empty.
Draw and animate the water drops: Extend
draw-world
, process-keys
, and
update-world
to handle the water drops. A down-arrow key
should create a new water drop at the same location that the plane had
when the key was pressed. The drops fall a few pixels (3 or 4,
depending on the speed you want) each time the world is updated.
Eliminate fallen drops: Edit your
update-world
function to remove any water drop that has
fallen past the bottom of the screen.
Draw the fires: Edit your draw-world
function to also draw the fires. You may use different size fire
icons based on the range of each fire's intensity.
Detect collisions between drops and fires: Edit your
update-world
to remove any water drop that hits a fire.
Also reduce the intensity of the fire each time a drop hits it (don't
worry about increasing the fire intensity yet).
Eliminate zero-intensity fires: Edit your
update-world
function to remove any fire whose intensity
has decreased to zero.
End the game when no fires remain: Develop the
game-over?
function to return true if there are no fires
remaining.
Increase fire intensity: Increase the fire intensity a small amount on each update when no drop has hit that fire.
You may use whatever images you wish for the pieces of the game
(the ones we used are below; feel free to use them or plain circles
and rectangles if you prefer). We used the built-in (in world.ss)
circle
operator to draw the water drops and the different
sized fire images for different ranges of intensity of fires. You do
not need to reverse the image of the plane when it reverses direction
or do anything fancy with the graphics.
Remove extinguished fires from the world: certain aspects of the game will be much easier to program if you do this.
Raise the intensity of the fire at a much lower rate than you drop it (or the game becomes unplayable). Our prototype raised intensity at 1/100 the rate of lowering it, for example. Use real numbers rather than integers for this.
If you choose to break this exercise down yourself yourself, we suggest you implement the game in stages. For example, start with a simple version that lets the user change the direction of the plane's movement, but has no fires or water. Once you have that working, add the water drops and get them to fall. Once that is working, add the fires. Get the fires to decrease in intensity when water hits them, then get them to increase in intensity when no water falls on them.
Use the "insert image" option under the "special" menu to load an
image into your DrScheme file; you can use define to give an image a
name. We used the circle
operator (defined in world.ss)
to get images for the water drops.
Icons are from school-clip-art.com (fire) and clipartguide.com (plane).