So far, the player can move the ship around the field of asteroids and even fire missiles, but none of the objects interact. I change all of that in the next version of the game. When a missile collides with any other object, it destroys that other object and itself. When the ship collides with any other object, it destroys the other object and itself. Asteroids will be passive in this system, since I don't want overlapping asteroids to destroy each other.
The Astrocrash06 program achieves all of this collision detection with the Sprite overlapping_objects() method. Also, I have to handle the destruction of asteroids in a special way. Remember that when a large asteroid is destroyed, two medium-sized asteroids are created. When a medium-sized asteroid is destroyed, two small asteroids are created. When a small asteroid is destroyed, nothing is created.
TRAP | Because all of the asteroids are generated at random locations, it's possible for one to be created on top of the player's ship, destroying the ship just as the program begins. I can live with this inconvenience for now, but I'll have to solve this issue in the final game. |
Figure 12.13 shows the program in action.
Figure 12.13: The ship's missiles now destroy asteroids. But be careful, as asteroids destroy the ship.
I add the following code to the end of Missile's moved() method:
# check if missile overlaps any other object for game_object in self.overlapping_objects(): game_object.die() self.die()
If a missile overlaps any other object, the other object and the missile are both destroyed.
Missile, like any class in this version of the game, needs a die() method. The method is about as simple as it gets:
def die(self): """ Destroy the missile. """ self.destroy()
When a Missile object's die() method is invoked, the object destroys itself.
I add the following code to the end of the Ship's moved() method:
# check if ship overlaps any other object for game_object in self.overlapping_objects(): game_object.die() self.die()
If the ship overlaps any other object, the other object and the ship are both destroyed. Notice that this method is exactly the same as Missile's moved() method. Again, when you see duplicate code, you should think about how to consolidate it. In the next version of the game, I'll get rid of this and other redundant code.
This method is the same as Missile's die() method:
def die(self): """ End the game. """ self.destroy()
When a Ship object's die() method is invoked, the object destroys itself.
Asteroid's die() method is more involved:
def die(self): """ Destroy asteroid. """ # if asteroid isn't small, replace with two smaller asteroids new_size = self.size - 1 if new_size: for i in range(2): Asteroid(screen = self.screen, x = self.get_xpos(), y = self.get_ypos(), size = new_size) self.destroy()
The wrinkle I add is that the method has the potential to create two new Asteroid objects. The method calculates the value of new_size, the size of the potential new asteroids. If new_size is either 1 or 2, then two new asteroids are created at the current asteroid's location. Whether or not new asteroids are created, the current asteroid destroys itself and the method ends.