Snowman by the pool. (Edited with OpenCV.)

Today was the first snow of the winter season here in Hangzhou, China. It was so nice to see snow again.

Most space shooters rely on a way to either improve the ship’s capabilities or on random power-ups that enemy characters pick up when they are destroyed. So for our space shooter we are going to create two types of power-ups: a shield and missiles. Each will have its own set of capabilities and restrictions.

Today we will focus on creating power-ups, and creating the functions to use the bonuses during our game. 

Types of power-ups

Shield: When an enemy is destroyed, there is a random chance that a shield will drop. The shield will then begin to move towards our ship and if our player collides with it, we can pick it up and earn extra points towards our score (score feature added later). A shield is displayed around our ship until our health is below 30, at which point it disappears to indicate that we are low on health.

Shield.

Missile: Similar to the shield, enemy ships have a chance to drop missiles. Our ship will have missiles for 4.5 seconds, at which point they will “run out”. If the player already has collected one missile power-up, they can collect another for a total of two missile power-ups.

Missile!

Let’s get started loading images and building classes for the power-ups.

CODE CAN BE FOUND HERE ON GITHUB.

Loading images

In def main( ), let’s locate and load the images for both our missile and shield images. We will use two separate images for the power-ups dropped by our enemies and for when our player uses them.

These missile_img and energy_shield images are used by our player when either the player fires a missile, or displays their shield power.

Here, we load and resize the images for the items dropped by the enemies and asteroids. We create a dictionary called power_images in line 2 that we will use later to determine which kind of power-up has been dropped.

In the while loop, create a group to keep track of all of the power-ups.

Create power-up classes

Let’s first create the Missile class which creates missile objects at the x and y location given, and updates the movement.

The Shield class will create a shield object that will be located at the player’s center, and whenever the player moves the shield needs to update with the player’s location so it looks like it is surrounding the player.

In lines 15 – 19, if the player’s shield is below 30, the shield will disappear, but if the player picks up another shield power-up then the shield will come back if their shield is over 30.

Finally, we need to create a PowerUp class that we will use when the enemy gets destroyed to generate randomly one of the power-ups.

In lines 5 and 6 we choose randomly between one of the power-ups in the dictionary, and then use that type of power-up. That’s it for the classes. Next, we need to update the Player class.

Player Class Updates

It’s been awhile since we updated the Player class, and there is quite a little bit we need to add. As the Player class is a bit long, I am going to omit certain parts and only show the updates. If you are interested in the whole Player class, either check out this tutorial or my GitHub.

In line 3, let’s add the missile_image to our Player’s arguments, and then assign it to the class in line 8. We create the shield variable and set it equal to 100.

We need a method to keep track of whether or not we have picked up any missiles. Since our missiles only last for a short period of time, we will also need to use the game timer to keep track of how long we have had them. self.upgrade in line 15 will increment by 1 if we have picked up the missile, and decrement by 1 if the timer has passed 4.5 seconds without picking up a new power-up. We check for this in lines 21 – 24.

Next, let’s update the shoot( ) function that is called in line 28 when we press the spacebar. If upgrade is still equal to 1, the player only fires bullets. If the player has collided with a missile upgrade, then upgrade equals 2 and we start shooting missiles from the left wing of the ship until the timer checks that 4.5 seconds has passed. We do a similar thing if upgrade equals 3, and we start to fire two missiles.

upgrade_power( ) in lines 58 – 63 checks to make sure we can’t get more than 2 missile upgrades.

Finally, let’s update the player object and add a shield object in the main game while loop.

Collision Detection

Now, we need to check if our ship has collided with a power-up and also check if enemies were destroyed and may randomly drop an upgrade. I will keep this short and try and to only include the important parts. 

Collision detection for player’s bullet and asteroids:

If asteroid is hit, there is small chance that a power-up will be dropped. If it is dropped we add it to the all_active_sprites list and powerups list. 

Collision detection for player’s bullet and enemy ships:

I just increased the chance that an item will drop if an enemy ship is destroyed. 

Check if enemy bullet hit player:

Here, we begin to subtract shield from the player. As of now, it won’t do anything except subtract until shield reaches 0, then refill it. 

Check for collision between asteroids and player:

If a player is hit by an asteroid, we deduct a random amount between 10 and 24 from the player’s shield. We also check here if the player’s shield is less than 0. 

Check for collision between enemy ships and player:

In line 2, if the player is hit by an enemy ship, we subtract 35 points from the shield. 

And finally the most important one, check for collision between power ups and player:

In line 2, call the spritecollide function to check for collisions between the player and powerups. In lines 6 and 10, check what type of upgrade we hit. If it’s the ‘shield’, then add 20 to shield, but if the shield is already >= 100, force it to 100. If it is a ‘missile’, then call the player.upgrade_power function. 

Results:

Missiles! Shields! Explosions! War!

Summary

We talked about two simple kinds of power-ups that we could added to our space shooter. You could always add homing missiles, or other kinds of defense weapons if you want. We also covered how to implement them in our game. 

Next time, I will discuss how to create the player window that displays our shield level, lives and the score. 

Reference

Images used in this tutorial can be found at kisspng.com.

CODE CAN BE FOUND HERE ON GITHUB.

Leave a Reply

Your email address will not be published. Required fields are marked *