Collisions, Score, and Game Over
With bullets and asteroids both on screen, it's time to make them actually interact: destroy asteroids you shoot, and end the game if one hits your ship.
Distance-based collision detection
import math
def distance(a, b):
return math.hypot(a.x - b.x, a.y - b.y)
For circular objects (ships, asteroids, bullets all drawn as circles/triangles with a radius), you don't need pixel-perfect collision, just check whether the distance between two centers is less than the sum of their radii:
def circles_collide(a, b):
return distance(a, b) < (a.radius + b.radius)
Bullets destroying asteroids
score = 0
for bullet in bullets:
for asteroid in asteroids:
if distance(bullet, asteroid) < asteroid.size:
bullet.life = 0 # mark the bullet dead so it gets filtered out
asteroid.hit = True # mark this asteroid for removal
score += 100
asteroids = [a for a in asteroids if not getattr(a, 'hit', False)]
bullets = [b for b in bullets if not b.is_dead()]
Rather than removing items from asteroids/bullets in the middle of the nested loop (which corrupts the loop you're iterating over), the pattern is the same as the bullet-cleanup from the last lesson: mark things as "should be removed" first, then filter both lists once, after the collision checks are done.
Ending the game
game_over = False
for asteroid in asteroids:
if circles_collide(player, asteroid):
game_over = True
if game_over:
font = pygame.font.SysFont(None, 64)
text = font.render("GAME OVER", True, (255, 60, 60))
screen.blit(text, (250, 260))
pygame.font.SysFont(None, 64) loads the operating system's default font at size 64, .render(text, antialias, color) turns a string into a drawable Surface, and screen.blit(surface, position) is how you draw any image or rendered text onto the screen, it's the same function you'd use to draw a sprite image.
WARNING
Once game_over is True, this snippet still keeps calling player.update()/asteroid.update() every frame unless you guard those calls too, remember to stop updating gameplay (but keep the event loop and drawing running) once the game has ended, otherwise the ship and asteroids keep moving invisibly under your "GAME OVER" text.