Pygame Shmup Part 13: Powerups (part 2)

Tags: python tutorial gamedev pygame

This is part 13 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:

Gun Powerups

Last time, we created a Powerup sprite that drops randomly from meteors when they are destroyed. We finished making the 'shield' type powerup work, and now we need to do the same with the 'gun' type.

There are a lot of things we could choose to have the gun powerup affect: fire rate, damage (although right now we destroy meteors with one hit), type of gun, etc. For this lesson, we’re going to make the player shoot more bullets, but to give us the flexibility to change it later if we want, we’re going to define a new Player method and call it when we grab a 'gun' powerup:

    if hit.type == 'gun':

To make this work, first let’s add some new properties to the Player sprite: power to track what the “power level” is (each pow can raise this by one), and a power_time so we can drop back down after a certain amount of time goes by:

    self.power = 1
    self.power_time = pygame.time.get_ticks()

The powerup method will set these properties:

def powerup(self):
    self.power += 1
    self.power_time = pygame.time.get_ticks()

And now we can change the shoot method to produce 2 bullets when power is greater than 1. We’ll make them spawn at the wingtips.

def shoot(self):
    now = pygame.time.get_ticks()
    if now - self.last_shot > self.shoot_delay:
        self.last_shot = now
        if self.power == 1:
            bullet = Bullet(self.rect.centerx,
        if self.power >= 2:
            bullet1 = Bullet(self.rect.left, self.rect.centery)
            bullet2 = Bullet(self.rect.right, self.rect.centery)

And lastly, we need to check the power_time by adding this to the player’s update:

# timeout for powerups
if self.power >= 2 and pygame.time.get_ticks() - self.power_time > POWERUP_TIME:
    self.power -= 1
    self.power_time = pygame.time.get_ticks()

Don’t forget to set POWERUP_TIME to 5000 (5 seconds) at the top.

Pow sounds

To wrap up the Powerups feature, we need some nice sounds to play when we pick up the items. I will leave that for you to add. Use ‘bfxr’ to find two sounds you like and load them like we did the other sounds, naming them something like shield_sound and power_sound. Then, just play each sound when the corresponding pow type is collided with. You can see the full game code below, but do try to make it work before you look.

Next time, we’ll finish up the game by adding a ‘Game Over’ screen.

Full code for this part

Part 14: Game Over Screen