Pygame Shmup Part 12: Powerups

Tags: python tutorial gamedev pygame

This is part 12 of our “Shmup” project. If you haven’t already read through the previous parts, please start with Part 1. In this lesson we’ll add some powerups that will occasionally appear.

About this series

In this series of lessons we’ll build a complete game using Python and Pygame. It’s intended for beginning programmers who already understand the basics of Python and are looking to deepen their Python understanding and learn the fundamentals of programming games.

You can watch a video version of this lesson here:

Powerups

Our game has come along quite far, but one thing we’re still missing is a way for our player’s ship to get stronger. There are many kinds of powerups we could think about adding, but for now we’re going to focus on two:

Pow sprite

To begin, we need to define yet another Sprite, this time to represent our powerup object. To make things simple, we can just copy the Bullet() class we already made and just make a few changes, since the behavior will be similar: start at a location (the location of a meteor that was just destroyed) and move downward, then kill the sprite if it goes off the bottom of the screen. For its image, we’re going to randomly choose between 'gun' and 'shield', which will be our two kinds of powerup.

class Pow(pygame.sprite.Sprite):
    def __init__(self, center):
        pygame.sprite.Sprite.__init__(self)
        self.type = random.choice(['shield', 'gun'])
        self.image = powerup_images[self.type]
        self.image.set_colorkey(BLACK)
        self.rect = self.image.get_rect()
        self.rect.center = center
        self.speedy = 2

    def update(self):
        self.rect.y += self.speedy
        # kill if it moves off the bottom of the screen
        if self.rect.top > HEIGHT:
            self.kill()

We’ll need to load the images in our asset loading section, using a dictionary to hold the images with the powerup type as the key:

powerup_images = {}
powerup_images['shield'] = pygame.image.load(path.join(img_dir, 'shield_gold.png')).convert()
powerup_images['gun'] = pygame.image.load(path.join(img_dir, 'bolt_gold.png')).convert()

Here are the images we’re using (click to download):

Spawning

To spawn them, we’ll need a group to hold them (for collisions):

powerups = pygame.sprite.Group()

Then, when a bullet destroys a mob, we want a (small) random chance that a powerup will drop:

# check to see if a bullet hit a mob
hits = pygame.sprite.groupcollide(mobs, bullets, True, True)
for hit in hits:
    score += 50 - hit.radius
    random.choice(expl_sounds).play()
    expl = Explosion(hit.rect.center, 'lg')
    all_sprites.add(expl)
    if random.random() > 0.9:
        pow = Pow(hit.rect.center)
        all_sprites.add(pow)
        powerups.add(pow)
    newmob()

Here, random.random() picks a random decimal number between 0 and 1, so only spawning if the number is greater than 0.9 means we have a 10% chance of a powerup dropping from a destroyed meteor.

Colliding with the Player

Now, we need yet another collision check, this time between the player and the powerups group. Add it right after the others:

# check to see if player hit a powerup
hits = pygame.sprite.spritecollide(player, powerups, True)
for hit in hits:
    if hit.type == 'shield':
        player.shield += random.randrange(10, 30)
        if player.shield >= 100:
            player.shield = 100
    if hit.type == 'gun':
        pass

First, we’re handling the shield powerup, which will give the player a random amount of shield back. The 'gun' powerup is a little bit more involved, so we’ll take care of that in the next part.

Next time, we’ll finish up the powerup code for the gun type.

Full code for this part

Part 13: Powerups (part 2)

Comments