Representing Objects With Game Models
00:11 Your Asteroids clone has various things inside of it: a ship, some rocks, and some bullets. Each of these things will be represented by a Python object. This allows you to write common code that stores and handles position and velocity values, and methods for using the objects.
01:48 You’ll need a circle inside of your sprite. And to describe that circle, you’ll need its radius. This is why I’ve chosen to specify a position value based on the center of the object. Even though when it’s blit to the screen, you’ll need to convert it to the top left corner coordinates. By using the center and a radius, you can quickly use circle-based collision detection.
To try and keep things separated, I’m going to write all the game objects in their own file. This is
models.py. Here, I’ve written a generic
GameObject that will form the basis of all the models moving forward. Inside of the
.__init__() method, I start out by saving the position.
The position is passed in as a point, an
(<x>, <y>) tuple, but for convenience’s sake, I’m going to convert that into a Pygame
Vector2 object. A vector is just a set of two numbers, but the Pygame implementation provides methods for doing math that will be useful when dealing with moving the object around and determining the distance between objects.
The second parameter to
.__init__() is the sprite that will be drawn. This is being stored on line 7 for future use. With the sprite passed in, you can use the size of the sprite’s rectangle to calculate a collision circle.
On the final line of
.__init__(), I’m storing the velocity. This is a tuple containing the speed and direction, and like
.position, it’ll be stored as Pygame
Vector2. With the object ready to be created, you’re going to need some methods for drawing, moving, and collision detection.
04:19 Without them, you’d have to do math on the x-coordinate then separate math on the y-coordinate. With vectors, instead you can just subtract and you’re ready to go. With coordinate conversion complete, all you have to do to draw the asset is blit it to the surface passed in. In this case, that’ll be the screen’s surface.
As you’re trying to create moving objects, every object has a velocity, and for each frame drawn, its position must change. The
.move() method updates this object’s position by moving it using the speed and direction stored in the velocity vector.
And finally, this handy little method uses the collision circle of the object to figure out if it overlaps with the collision circle of another object. The
.distance_to() method on a vector returns the difference between two points. In this case, the distance is between the center of this object and the center of the object passed in to the method. With the distance known, a little math using the radii of the two objects will determine if they overlap.
Let’s start by adding a ship. Line 15 loads the spaceship sprite, and line 16 creates a
GameObject that represents that ship. The ship starts out at position
(400, 300), which is the center of the screen.
06:45 This means for every frame of the game, this object will move one pixel to the right. To help test the collision code, line 21, just below the definition of our rock, creates a counter that will be used to track how many collisions have happened. Let me just scroll down here.
To be able to see some results, our game objects have to be drawn. Lines 40 and 41 call our object’s
.draw() methods, passing in the background screen as the surface to be blitted upon. Note that the drawing of these objects has to be after line 39, the drawing of the background. If the order were different, the background image would overwrite the sprites.
07:37 The final bit of code here is just a quick little test. During each frame, a collision detection is done between the ship and the rock. If there’s a collision, the collision counter will be incremented and the new count will be printed to the terminal. Let’s see our progress and fire up Pygame.
08:29 Ready to go? Okay, action. There’s our rock. There’s a collision happening, and the rock has passed, so the collision detection alerts stops. In a real game, you’d want something to happen to the ship in the case of a collision.
08:44 But for now, all I’ve done is detected. Also, in a real game, you’d want to figure out what to do with the rock when it went offscreen. Currently, as I’m yammering along here, the game is still running and the rock is still moving. It just keeps going right.
08:59 The longer I talk, the further away it goes. This is a waste of computing resources. If you’ve got a lot of assets, computing all the stuff not on the screen becomes expensive, so in the future, let’s do something about that. In the meantime, go little rock, go!
Become a Member to join the conversation.