home—lectures—recipe—hws—exams—D2L—zoom (snow day)
hw04: structs
…for Asteroids
Due (at start-of-class):
- Part (a) due
Sep.21Feb.13 (Thu) 23:59 on D2L, but no hardcopy.
- Part (b) due
Sep.21Feb.18 (Tue) with 10% extra, or Feb.19 (Wed) 23:59 for regular credit,
both D2L and hardcopy.
- Your submitted file should be named “hw04.rkt”,
plus (for part (a))
a single .java files (no .zip/.jar, thanks!).
Standard instructions for all homeworks:
- Your name,
the assignment-number,
and
the URL of this assignment
must be in a comment at the start of the file.
- Any code which results in syntax errors
will generally not earn more than 50%
of the points-possible.
For grading, I will ignore any commented-out code
(unless the problem is explicitly asking for commented-out code, ’course).
- If your hardcopy is more than 1page, it must be stapled.
- Format well
(in particular,
each open-paren should be preceded by a space or start-of-line, for now).
Familiarize yourself with the
arcade game
Asteroids.
We will write our own version,
starting with this homework (structs)
and finishing with next homework (lists).
In our simplified version:
We will write a simplified version which
only needs to deal with:
the ship, asteroids, and bullets.
It does not need to deal with:
score,
number-of-lives,
having more than one level,
or
ufos.
For each of the objects which we're modeling, we'll write be writing three functions:
how they draw, move, and (only for ships) handle a key-event.
part (a): Racket & Java
- Give a Java record and a racket struct for a ship.
In addition to this datatype-definition,
give at least two example ship objects/structs
(the design recipe's #2),
and the template (the design recipe's #3).
hint: Thoughts/advice on
fields below.
Create (in both racket and Java),
a function move-ship which
takes in a ship, and returns
a ship one tick
of time later,
ignoring
any exterior factors like
asteroids or bullets or acceleration/key-presses.
Do account for wrapping around the screen;
you can (should) have a couple of named-constants
for the screen's height and width (perhaps 800x600 or so).
The Java and racket versions should both work in the same way:
returning a new object, rather than mutating any fields
(Cf. how we wrote enbiggen in both
racket
and
java).
Note: This method has nothing to do with a gui or drawing.
Updating the ship's fields is about the model, not the view.
(Later we will write draw-ship below, though in racket-only.)
part (b): Racket only
The following functions only need to be done in Racket (not Java).
- Define structs for asteroids or “astrs”,
and for bullets.
(Of course, still complete steps 1-3 of the design recipe.)
For each type of data,
make four examples-of-the-data:
two before versions, and two corresponding after-moving versions.
(This will help with test cases.)
- Write move-asteroid and move-bullet, similar to move-ship above.
Note: We will not be using struct-inheritance, so these functions might be very similar to each other.
In other games, there are sometime very-different movement rules for the player, enemies, and bullets.
- Drawing functions:
Write draw-ship : (-> ship? image? image?)
which draws a ship onto the provided background-image.
Then do similarly for draw-asteroid and draw-bullet.
notes: - The caller might pass any image as the background.
For example you can test with
,
which is exported from
videogame-helpers.rkt as house-with-flowers.
- The library function place-image can be helpful.
- Write ship-handle-key,
which takes in a ship and a key-event?,
and returns a new ship which has processed that key-event.
notes: - Playing the demo above, we see there are only four key-presses that actually do anything
in the game. And firing, while it changes the overall world (adds a bullet),
doesn't actually change the ship, so this function won't care about firing;
we'll handle that next week, when we create an entire world struct.
- You can compare two key-event?s
with string=?, but key=? (from (require 2htdp/universe))
is more appropriate. Equal credit will be awarded, either way.
- You might want to review
notions of distance vs. velocity vs. acceleration;
one explanation is at
physicsclassroom.com.
- Note that a key-event never moves the player.
Only clock-events (ticks) actually move the player; the
key-events are instantaneous in the game-model.
However, a key-event can accelerate a player (i.e. change its speed).
- Collision detection:
Write
ship-collide-asteroid?,
and
asteroid-collide-bullet?,
which each return a boolean.
We'll ignore asteroids colliding with other asteroids,
as well as a ship colliding with bullets (since that's friendly fire).
Note: You are free to use the provided helper-function overlap?
in videogame-helpers.rkt.
It takes in any two rectangles;
your collision-functions can be a thin wrapper around overlap? by expediently
approximating collisions as overlapping bounding boxes of the two objects.
- The last piece of single-object behavior we need is when
a (non-tiny) asteroid collides with a bullet, and it breaks into 2 or 3 smaller asteroids.
Write a function that we can call 2 or 3 times, to generate the smaller asteroids.
It should take in one (non-tiny) asteroid,
plus some extra bit of info which determines which smaller asteroid
is returned.
E.g. you might pass in an angle for the new-resulting-asteroid's direction.
Myself, I used a vector indicating the new asteroid's acceleration relative to
its parent.
Next assignment, when we have lists,
we'll write a function that takes one (non-tiny) asteroid
and returns a list of 2 or 3 smaller asteroids.
For the future…
We still don't have a running game yet.
That will entail processing lists of asteroids and lists of bullets.
We'll deal with lists on the next homework
(as an application of union and structure-types working together,
rather than any new concept or syntax!).
That's where we'll write code for (say) drawing an entire list of asteroids or list of bullets,
as well as an overarching game struct which holds the various pieces of the games
(one ship and two other lists).
Design considerations
Fields, in general
- When declaring fields, give them good (and perhaps short) names.
Do remember to indicate their units (if appropriate), along
with any other non-obvious info.
- Many fields have multiple possible representations.
For example,
for a ship's direction you might use
an angle what units? what does angle 0 mean?,
or a pair of coordinates, or even
those two coordinates further wrapped inside single field of type coordinate-point
(if I defined my own new struct for that).
These all have their strengths and weaknesses.
- Don't make invariant information into a field:
When wondering if certain information should be a field of an object,
imagine having 100 of those objects.
Would every single object have the same value for a field?
If so, then it shouldn't be a field!
Instead, info that's invariant across all objects of a type
should be a single global/module/class variable
(perhaps a named-constant) instead.
Some fields particular to this assignment
- My ship had 5 fields: two pairs of numbers, plus another number.
There is no image as a field,
per invariant above.
- One particular thing to think about, before you start coding:
Saying a field holds “The location of a ship on-screen” is mildly not-fully-defined:
Compare to “the location of Virginia is 37.926868° N, -78.024902° W” --
while admirable to tell me our state's exact location to within 9″,
how this value perhaps confusing/unclear?
Can you make your field-description for an object's screen-location more precise
than just "the object's coordinates in pixels".
Library conventions
Another thing guiding our choices might be the libraries that we
want to interact with.
In this case, we'll be using the 2htdp/image
and 2htdp/universe, so I'll point out the following:
- All coordinates/lengths are real?.
So you can certainly make a circle whose radius is 8.5 pixels.
(When drawing such a circle, our grid-based pixellated screens might
end up drawing a mere approximation of the true circle.
But heck, that's
already true in libraries that restrict the concept of a radius to an integer.)
- The image-library's function rotate uses degrees,
so that's a convenient unit for your own code/fields to use.
But if calling (say) cos
be sure to convert
deg->rad!
- The function place-image
wants an x/y offset as two separate coordinates
(and not a single, bundled coordinate-point struct),
so our representation might follow that lead.
It also uses the standard computer-graphics conventions
that 0,0 means the upper-left corner, and +y means downward.
You don't need to document these conventions in your fields;
it's standard enough to be assumed.
Yeah, it's low-key annoying that these two computer-graphics conventions
defy standard pre-algebra's more reasonable conventions.
- Note that place-image
places an image's center at a specified coordinate.
This differs from some drawing libraries that use
an image's northwest corner as its location.
In addition, the provided overlap? also wants
coordinates-of-centers of rectangles.
I strongly suggest you use this convention in your fields.
- The student-extras.rkt includes the function
modulo/real: e.g. (modulo/real 3.5 2) returns 1.5.
This is helpful for wrapping-around, when your coordinates are reals
instead of just integers.
- I suggest using simple shapes (like mere rectangles) for
all your drawing-functions for the game.
You are welcome to be much fancier, though it won’t earn you additional credit.
You are welcome to use jpg/png/bitmaps, but make sure
you have the legal right to copy them —
e.g. from sites like
classroomclipart.com
or libraries like
planetcute
.
Please cite your source, of course!
- You might find struct-copy helpful; it copies a structure, letting
you change a few fields:
(struct-copy my-book [num-pages (add1 (book-num-pages my-book))] [author "me"])
is equivalent to
(make-book (book-title my-book) "me" (add1 (book-num-pages my-book)) (book-is-copyrighted? my-book)).
home—lectures—recipe—hws—exams—D2L—zoom (snow day)
 This page licensed CC-BY 4.0 Ian Barland Page last generated | Please mail any suggestions (incl. typos, broken links) to ibarland radford.edu |
 |