Assignment 6: Zombies
This assignment is due on Wednesday, 9/27 at 11:59 PM. Submit it using the Handin server as assignment a6.
Important NoteWhenever we say to develop a function, we mean that you need to follow the design recipe.
For this assignment, you will program a very simple single-player video game. The players goal will be to escape hungry zombies for as long as they can. The world will be represented as a scene containing a player icon (for example, a small green circle) and many zombie icons (for example, small red circles).
In your program, the player is just a position in the scene, which you will implement as aPosn. The actual player will want to be able to move to another position (to avoid, for example, being eaten). While playing, they will see their icon move towards the position of a mouse click (or drag).
Likewise, zombies are just positions in the scene, which you will also implement asPosns. Zombies sense that there is something delicious at the players position, and so will move there.
The player has a fixed distance (in pixels) they can move each tick. There is also a fixed zombie speed.
1 approach
Now the problem is, given a player position and a mouse click position, how do you compute the new player position after one tick, assuming that the player moves in a straight line towards the mouse click position? Likewise, how do you compute the new zombie position after one tick, assuming the zombie moves in a straight line towards the player?
You will define a function approachwhich will answer both questions. approachwill take two positionsp,p 0and a distance per ticksand return a positionp.
Intuitively, heres a way to findp. Measure thedistance(in pixels) fromptop 0. Also, determine in whichdirectionplies with respect top 0(which we will represent as a point on the unit circle). The idea is thatpshould lie in exactly the same direction, but at a smaller distance: a distancespixels smaller.
To recapitulate, you can typically findpby following these steps: (1) determine the distance and direction ofprelative top 0; (2) subtractsfrom the distance; and (3) compute a newPosnfrom the new distance and the same direction.
We say typically because there is an important exception to consider. Suppose thatpandp 0are already close: that is, withinspixels. Thenpandp 0should just be equal. The player does not overshoot their destination; a zombie stops moving when it has found its meal.
Exercise 1
Develop the following three functions:
; posn-sum : Posn Posn -> Posn ; posn-diff : Posn Posn -> Posn ; posn-scale : Number Posn -> Posn
posn-sumcomputes the sum of two Posns by creating a newPosnfrom the sum of the x-coordinates and the sum of the y-coordinates. posn-diffsimilarly computes the difference of two Posns by subtracting the second x-coordinate from the first and the second y-coordinate from the first. Finally, posn-scalescales the givenPosnby multiplying both the x- and the y-coordinates by the given number.
Exercise 2Here we provide the definitions of three helper functions that compute distance, direction and atypicalapproach. (Note that these may work only as well as your functions from Exercise 1).
Provide the missing unit tests for distand for approach-helperand the missing purpose statement for approach-helper.
Finally, develop approach. The first argument is the position to be updated. The second argument is the unchanging position being approached. The third input is the speed (pixels/tick).
Notice that approach-helperdoes not handle the case just described where the input positions are very close. approachmust handle this case as well.
; dist : Posn Posn -> Number ; computes the distance between two Posns ( define ( dist p0 p1 ) ( sqrt ( + ( expt ( ( posn-x p0 ) ( posn-x p1 ) ) 2 ) ( expt ( ( posn-y p0 ) ( posn-y p1 ) ) 2 ) ) ) ) ( check-expect ) ( check-expect ) ; direction : Posn Posn -> Posn ; computes the direction of a Posn with respect to another Posn, ; representing direction as a Posn on the unit circle ( define ( direction p p0 ) ( posn-scale ( / 1 ( dist p p0 ) ) ( posn-diff p p0 ) ) ) ( check-within ( direction ( make-posn 400 400 ) ( make-posn 200 200 ) ) ( make-posn ( / ( sqrt 2 ) 2 ) ( / ( sqrt 2 ) 2 ) ) .01 ) ( check-within ( direction ( make-posn 0 400 ) ( make-posn 200 200 ) ) ( make-posn ( 0 ( / ( sqrt 2 ) 2 ) ) ( / ( sqrt 2 ) 2 ) ) .01 ) ( check-within ( direction ( make-posn 400 0 ) ( make-posn 200 200 ) ) ( make-posn ( / ( sqrt 2 ) 2 ) ( 0 ( / ( sqrt 2 ) 2 ) ) ) .01 ) ( check-within ( direction ( make-posn 0 0 ) ( make-posn 200 200 ) ) ( make-posn ( 0 ( / ( sqrt 2 ) 2 ) ) ( 0 ( / ( sqrt 2 ) 2 ) ) ) .01 ) ; approach-helper : Posn Posn Number -> Posn ; ( define ( approach-helper p p0 s ) ( posn-sum p0 ( posn-scale ( ( dist p p0 ) s ) ( direction p p0 ) ) ) ) ( check-expect ) ( check-expect ) ; approach : Posn Posn Number -> Posn ; ( define ( approach p p0 s ) ) ( check-expect ) ( check-expect )
2constants
The goal of this brief section is to define constants for your game.
Exercise 3
Define constants pspeed, zspeed, backgroundand close-enoughcorresponding to the player speed, the zombie speed, the game background and the distance from the player position (in pixels) under which a zombie gets to have its meal (and the game ends). For the game background, a 400 x 400 empty scene works, but feel free to be creative.
3 pworld
This section will focus on player movement.
Exercise 4Develop a data definition and a struct called pworldwhich has two fields. One field stores aPosnwhich is the player position and the other field stores aPosnwhich is the goal position (towards which the player moves).
Exercise 5Develop a function move-playerwhich takes and returns aPworld. move-playerwill be an on-tick handler for big-bang . In the game, move-playerwill move the player closer to the goal position stored in the inputPworld. Use approach.
Exercise 6Develop a function update-pgoalwhich takes aPworld, twoNumbers and aMouseEventand returns aPworld. update-pgoalwill be an on-mouse handler for big-bang . In the game, either a button-down or drag event from the mouse will change the goal position towards which the player is moving.
Exercise 7Develop a function draw-pworldwhich takes aPworldand returns anImage. In the game, you should have an image for the player positioned on the background according to the player position data stored in the inputPworld. (A small green circle works, but feel free to express yourself.)
Exercise 8Develop a function run-pworldwhich takes an initial World for big-bang, namely apworld, and runs big-bang with draw-pworld, update-pgoaland move-player. The purpose of run-pworldis only to make sure that you have player movement working well in your game before you add zombies.
4 zworld
Exercise 9Develop a data definition for a list of zombies. Again a zombie is aPosn. Develop a data definition and a struct called zworldwhich has two fields. One field stores aPworldand the other field stores a list of zombies.
Exercise 10Develop a function called draw-zworldwhich takes aZworldand returns anImage. This function will be passed to big-bang as a to-draw argument. The goal is to add icons for zombies on the image produced by draw-pworld. Zombies may be represented by small red circles or something else of your choosing. Be sure to develop a helper function to process theListOfZombiesand of course use draw-pworld.
Exercise 11Develop a function called move-zombieswhich takes aListOfZombiesand aPosnand returns aListOfZombies. This is a helper function for a handler for on-tick . In the game, move-zombieswill move all of the zombies towards the inputPosn. Use approach.
Exercise 12Develop a function called move-everyonewhich takes and returns aZworld. This function is a handler for on-tick . In the game, move-everyonemoves the player icon towards the goal position stored in thePworldwhich is stored in the givenZworld; it also moves all of the zombies towards the player position. Use move-zombiesand move-player.
Exercise 13Develop a function called update-pgoal-2which takes aZworld, twoNumbers and aMouseEventand returns aZworld. This function is a handler for on-mouse . In the game, it updates the goal of the players movement to that of the inputxandycoordinates. Use update-pgoal.
Exercise 14Develop a constant called ten-zombieswhich is a randomly generatedListOfZombiesof length 10. Use random .
Exercise 15Develop a function called the-endwhich takes aZworldand returns aBoolean. This function will be passed to big-bang as a stop-when argument. Its purpose is to signal when your big-bang program should end. Your game will run as long as and only as long as the-endreturns #false. Use your constant close-enoughand the function dist. This function will require a helper to process aListOfZombies.
Exercise 16Define a constant runwhich is defined to be big-bang applied to the functions developed above for your game. Define theListOfZombiesof the initialZworldto be ten-zombies.
Extra funDevelop a function called generate-zombieswhich takes a natural number and returns aListOfZombies. Each zombie created by generate-zombiesis a randomPosn. You will use random and check-random . (Both of these as well as the template for recursively defined functions on the natural numbers will be discussed in class.) Use generate-zombiesin place of ten-zombies.
Reviews
There are no reviews yet.