The Python Game Book

code games. learn Python.

User Tools

Site Tools




This is an old revision of the document!

Step 019 - Homing missiles

In this example game, two players can fire bullets and rockets at each other or at big nasty monsters.

Bullets have a short range, but steal hitpoints if hitting a player or a monster.

There are 2 different kind of rockets:

  • a “light”, weak damage, fast flying variant. Short lifetime. Can be shot down.
  • a “heavy”, heavy damage, slow flying “sliding” variant. Longer lifetime. Can not be shot down, but it's flightpath can be disturbed if hit.

Both types of rockets aim automatically toward the target. While the “light” rockets move in the direction of their heading (boring), the “heavy” rockets “slide” like in open space, making more interesting flight patterns.

A player can store a maximum ammo of 32 rockets (see class Player, self.rocketsmax). The first 16 rockets are light rockets, the others are heavy rockets.

Not shooting increase the stock of missiles of each player (see the blue rocketbar above each player)

If no more monsters are present, the players can fight each other (duel mode). New monsters can be created my pressing <key>m</key>.

If both players are shot down by monsters, the monsters start fighting themselves (Overtime). You can press <key>o</key> to get more overtime and watch the monsters fighting each other.

Monster states

Each 15 seconds, (see class Monster, self.hunttime) the monster has a chance to select a new target.

Each monster has a primitive State_machine, cycling between the three states “do nothing”, “shoot bullets at target” and “shoot rockets at target”. Each “state” is exactly 3 seconds long. This is the code line to see in what “state” or “phase” a monster currently is (inside class Monster, def update):

self.phase = self.phases[int(self.alivetime) % 3 ]
Self.alivetime is a variable counting the time (in seconds) of existence of a monster. The %-sign is the modulo operator. It doesn't return the result of a division, but instead the remainder.

As you can see in this example, the remainder cycles between 0 , 1 and 2 if the divisor is 3:

for x in range(31): # python2.x
   print x, "divided by 3 =", x/3, "remainder:", x%3,"float result:", x/3.0

0 divided by 3 = 0 remainder: 0 float result: 0.0 
1 divided by 3 = 0 remainder: 1 float result: 0.333333333333 
2 divided by 3 = 0 remainder: 2 float result: 0.666666666667 
3 divided by 3 = 1 remainder: 0 float result: 1.0 
4 divided by 3 = 1 remainder: 1 float result: 1.33333333333 
5 divided by 3 = 1 remainder: 2 float result: 1.66666666667 


All classes in this game derive from pygame's Sprite class.

additional resources

source code on github

To run this example you need:

file in folder download pygame Download the whole Archive with all files from Github:
player_red2.png pygame/data
player_blue2.png pygame/data
xmonster_s.png pygame/data
xmonster_fire_s.png pygame/data
xmonster_left_s.png pygame/data
xmonster_right_s.png pygame/data
claws.ogg pygame/data
wormhole.ogg pygame/data
bomb.ogg pygame/data
shoot.ogg pygame/data
beep.ogg pygame/data
explode.ogg pygame/data

View/Edit/Download the file directly in Github:

click reload in your browser if you see no code here:

comment this page


en/pygame/step019.1588534520.txt.gz · Last modified: 2020/05/03 21:35 by horst