This is a sketch I made of what the board might look like in Phevo. Some of the elements important to the game are already present.
Phevo is a game for two players that illustrates principles of genetics, biodiversity, and epidemics in a colorful, competitive arena. It is a little like Battleship for germs.
Take a peek at the fifth file. All that's been added is a new window title at line 191 ("Lincoln Versus Kitties"), creating a few sound objects starting at line 201, and few calls sprinkled around the file that play those sounds at the right time. I'll leave those for you to discover, but their placement should make sense at this point. Also, note how easy it is to add sound effects here in just a couple of lines!
And that is that... for making space invaders. But what about other games? Using other languages?
First off, the basics are always the same. Collect input. Make decisions. Wipe away the old drawings and paste on some new ones. Repeat.
Fine, fine, there are a couple more things happening in the fourth file.
First, on line 261, we have this line:
player_laser_sprites.add( PlayerLaserSprite( player_sprite.rect.midtop ) )
Wuh? All that does is ask that a new laser sprite be added to the board every time we hit the spacebar. And we ask that it appear in the area of the player_sprite... at the middle top of it, to be exact. Once we've added the sprite, it just goes, passed on its own rules established in "update." Bang!
If you look in the update function for the EnemyClass, you'll see that is does the exact same thing for enemy laser blast, except that it does it randomly instead of at every press of the spacebar.
Okay, open up the fourth file, and let's get nuts!
Now we've added three new sprite classes. Heavy! Well, not really. They do the same thing as the PlayerSprite class, they're defining new "stickers" that we can place on our screen.
What are the differences? Well, they load up different images and, therefore, are different sizes. The area that each takes up is called its bounding box--that will help us figure out how they will react to each other. More on that later.
They also have different update functions. The enemy will move around in a given direction until it hits a boundary, then it will bounce back in the reverse direction. It will do this for every frame--keeping moving one way until it can't, then move the opposite. Dumb AI, but it works.
Okay, keep looking at that third file. In the main function, we've added a couple new variables called player_sprite and player_sprites. player_sprite creates a new sprite, or "sticker" as we've been calling it. It does this by instatiating the PlayerSprite class. All this means is that we use the PlayerSprite class, which is just a definition, to create an actual sprite that we can move around on the screen. Since this is a one-player game, we just create one sprite and add it into the player_sprites (note the plural) group.
Now let's move it around! If you look in the event loop, you'll see we've added a few more key commands. These new commands set the velocity for the player sprite. It does not, however, move the sprite! This is important to remember. The keys are changing values of the sprite, but we leave it to the sprite to move itself! Let's see how this happens.
Okay, we're in control, but so what? This is boring! So, let's start blitting a few more things on here.
Open the third file. Near line 71, you'll see a line like this:
class PlayerSprite( pygame.sprite.Sprite ):
This is a class, the chief concept in object-oriented programming. DO NOT PANIC! Object-oriented code is designed to make your life easier, not harder. This class is a sprite, and you can think of it like a sticker or one of those animated Monty-Python characters. All a class does is define what makes a sticker a sticker. In this case, the sticker represents a player on the screen.
Ok, now open the second file. The first thing you'll notice is that we've added to functions, loadImageFile and loadSoundFile. Don't sweat these. They're just handy wrappers around a few functions that help us load up files that are located in the data subfolder. Feel free to use these as is in your own prototypes. They work well, and you almost certainly won't need to modify them.
Next, in the main function, we use the loadImageFile function to pull in the background image. Then we use the screen.blit function to blit that image.
Wait, blit? Wazzat? Blitting is like pasting an image onto the screen. Everytime we update graphics on the screen, we "blit" them. Think of this like a Monty-Python clip art animation. Right now, there's just the background, but we'll be pasting a few more things on here later.
Open the first file in the demo (01_lincolnkitty_basics.py) in a Python editor. This editor might be Idle, which usually comes with Python, your own favorite development environment, or even just a simple text editor.
This file is the skeleton from which you can build just about any prototype. It loads up the pygame and other important modules, creates a main function, sets up the screen, and start running (although only briefly, since nothing is happening yet.)
The most important thing to observe here is the "while" statement. This is the "main loop" of the application. It will repeat, over and over again, for every frame of the game sent to the screen (which we've set to be updated at 60 frames per second.)
Copyright Mike Edwards 2006-2009. All content available under the Creative Commons Attribution ShareAlike license, unless otherwise noted.