mycourses.unh.edu
,
find CS414, and find the assignment. Then click "Submit
Assignment" to upload your main file,
asteroids.py
,
plus any other files you have created.
The game ends successfully when you have destroyed all the rocks. The game ends in failure when a rock hits the ship.
If a rock passes through the right edge of the play area, it re-appears on the left side. Similar things happen when a rock passes through the other sides: it reappears on the opposite side.
Here is a screenshot showing the game in action:
update_scene
function:
def update_scene(): global time_before time_now = time.time() time_elapsed = time_now - time_before move_objects(time_elapsed) draw_objects() time_before = time_now t.ontimer(update_scene, 100)The last line of the function:
t.ontimer(update_scene,100)
causes
the update_scene()
to be called 10 times per second.
As you can see, each time the function is called, it gets the current time, and finds out how much time has elapsed. It uses this to move the objects, and draw them in their positions.
The objects in the game (the rocks, the bullets, and the ship) move at constant speed, in straight lines. They also may rotate, as they move (only the rocks rotate, though).
Each object will need the following information (seven numbers):
T
is the time elapsed. Then
x += vx * T y += vy * T angle += turn_rate * T
Each object needs seven numbers to describe its motion.
We can simply store this in a list with 7 floats, for each
object: [x, y, vx, vy, angle, turn_rate, size]
.
Let's call such a list a motion record. You
will need these motion records, for the whole game:
def move_object(motion_record, T): vx = motion_record[2] vy = motion_record[3] rate = motion_record[5] motion_record[0] += vx * T motion_record[1] += vy * T motion_record[4] += rate * T
In the screenshot above, the rocks have different shapes and sizes. In our game, all rocks will have the same shape, but may be of different sizes.
Drawing a bullet is simple. We just draw a dot which is, say 3 pixels wide:
def draw_bullet(motion_record): x = motion_record[0] y = motion_record[1] turtle.penup() turtle.goto(x, y) turtle.dot(3)To draw a rock, we have to consider its x y position, and its rotation angle:
def draw_rock(motion_record): x = motion_record[0] y = motion_record[1] angle = motion_record[4] size = motion_record[6] turtle.penup() turtle.goto(x, y) turtle.setheading(angle) turtle.pendown() ... then, a sequence of turtle.forward(...), and turtle.left(...) function calls, to draw a rockAnd drawing the ship is similar to drawing a rock.
To fire a bullet, it should appear on the tip of the ship, and start moving. So, we must get its x y position, based on the ship's position and angle. Its velocity will also depend on the ship's angle.
You will need these values:
x_ship
and y_ship
(from the
ship's motion record)
angle
(from the ship's motion record)
nose_length
the distance from the ship's
center to its tip.
bullet_speed
(how fast the bullet moves, in
pixels/second).
ux = math.cos(math.radians(angle))
uy = math.sin(math.radians(angle))
x = x_ship + nose_length * ux
y = y_ship + nose_length * uy
vx = speed * ux
vy = speed * uy
If a rock hits the ship, the game is over. If a bullet hits a rock, the rocks is split into smaller rocks, or the rock is destroyed. So, need to know how to check if two objects have collided. Here, you should use a very simple test, which is approximate: just pretend that each object is a circle.
Two circles will overlap if their center-to-center distance is less than the sum of their radiuses:
def collided(x1, y1, radius1, x2, y2, radius2): dx = x1 - x2 dy = y1 - y2 distance = math.sqrt(dx * dx + dy * dy) if distance < (radius1 + radius2): return True else: return FalseAll you need to do is figure a reasonable radius for each object. Then you should call this function, and pass it the centers and radius of the objects you think may have collided.