First, we'll draw an explosion...
Nothing special. Just a bunch of ellipses. I've created two images (...the second one is just a copy of the first but rotated by 45 degrees), so that I can animate it.
My actual explosion is white, with no background, but that won't show up against the white background of this webpage, so I've added a black background to it here. Your explosion image should not have a background color.
You'll be seeing a lot of this explosion in the game, so it's best to keep it small and simple. Mine is approximately the size of my strawberry enemy.
Detecting when Enemy is Hit
Same as in previous games, we can detect a hit using
collidelist(). If a collision occurs, we'll remove both the bullet and the enemy.
for bullet in bullets: hit = bullet.collidelist(enemies) if hit != -1: bullets.remove(bullet) enemies.remove(enemies[hit])
for loop allows us to iterate through every bullet, and for each bullet we'll check which enemy collided with it.
collidelist() function gives us the index of the item that collided with the bullet. If
hit is equal to -1, that means no collision, and we won't need to do anything. If
hit is NOT -1, we'll remove the bullet and remove the enemy.
To remove the enemy, we'll use the
remove() function, and provide it with the enemy that is hit. Since
collidelist(), only gives us the index, we'll need to retrieve the collided enemy using
Creating an Explosion
The explosion effect isn't absolutely necessary, but it makes the game look more professional. We can have multiple explosions on screen at any time, so as usual, we'll create a list for it...
explosions = 
Each time a bullet hit an enemy, we'll add an explosion at the spot where the enemy was and add it to the explosions list.
explosion = Actor('explosion1') explosion.x = enemies[hit].x explosion.y = enemies[hit].y explosions.append(explosion)
Make sure you place this code before the
enemies.remove(). If you had removed the enemy first, you won't be able to get it's x and y.
Since I have two explosion images, I'll add both of them to
images and set an fps.
explosion.images = ['explosion1', 'explosion2'] explosion.fps = 8
Next, I'll set a variable inside explosion, which I'm calling
life. You can use any variable name you want. This variable will store a countdown that represents how long the explosion will be displayed. Feel free to change this number and see what it does.
explosion.life = 15
We only want the explosion to appear for a short while, so we'll decrease
life on each update, and when it reaches zero, we'll delete away the explosion. We'll also run the
animate() function here, so that the explosion will look animated.
for explosion in explosions: explosion.animate() explosion.life -= 1 if explosion.life == 0: explosions.remove(explosion)
Finally, we'll need to draw the explosion...
for explosion in explosions: explosion.draw()
I'm drawing the explosion before the enemies, so that the enemy will appear on top of it (...if they overlap). Depending on the effect you want to achieve, you can also do it the other way round.
At this Point...
Now you should be able to destroy the enemies!
import pgzrun import random from pgzhelper import * WIDTH=800 HEIGHT=600 player = Actor('player') player.x = 400 player.y = 500 bullets =  bullet_delay = 0 background_images = ['background1','background2','background3'] backgrounds =  background = Actor(random.choice(background_images)) background.x = 400 background.y = 300 backgrounds.append(background) background = Actor(random.choice(background_images)) background.x = 400 background.y = -300 backgrounds.append(background) enemies =  explosions =  sounds.main_theme.play(-1) def update(): global bullet_delay if keyboard.up: player.y -= 5 if keyboard.down: player.y += 5 if keyboard.right: player.x += 5 if keyboard.left: player.x -= 5 if player.x < 25: player.x = 25 if player.x > 775: player.x = 775 if player.y < 30: player.y = 30 if player.y > 570: player.y = 570 if keyboard.space and bullet_delay == 0: sounds.sfx_sounds_interaction25.play() bullet_delay = 5 bullet = Actor('player_bullet') bullet.x = player.x bullet.y = player.y bullet.angle = 90 bullets.append(bullet) if bullet_delay > 0: bullet_delay -= 1 for bullet in bullets: bullet.move_forward(15) if bullet.y < 0: bullets.remove(bullet) for background in backgrounds: background.y += 3 if background.y > 900: background.y -= 1200 background.image = random.choice(background_images) if random.randint(0, 1000) > 980: enemy = Actor('enemy1_1') enemy.images = ['enemy1_1', 'enemy1_2'] enemy.fps = 5 enemy.y = -50 enemy.x = random.randint(100, 700) enemy.direction = random.randint(-100, -80) enemies.append(enemy) for enemy in enemies: enemy.move_in_direction(4) enemy.animate() if enemy.y > 700: enemies.remove(enemy) for bullet in bullets: hit = bullet.collidelist(enemies) if hit != -1: bullets.remove(bullet) explosion = Actor('explosion1') explosion.x = enemies[hit].x explosion.y = enemies[hit].y explosion.images = ['explosion1', 'explosion2'] explosion.fps = 8 explosion.life = 15 explosions.append(explosion) enemies.remove(enemies[hit]) for explosion in explosions: explosion.animate() explosion.life -= 1 if explosion.life == 0: explosions.remove(explosion) def draw(): screen.clear() for background in backgrounds: background.draw() for explosion in explosions: explosion.draw() for enemy in enemies: enemy.draw() player.draw() for bullet in bullets: bullet.draw() pgzrun.go() # Must be last line