I recently created a simple implementation of the classic arcade game “Asteroids” using Pygame, based on the “Build an Asteroids Game” project from boot.dev. This project was a fun way to explore game development and object-oriented paradigms in Python. In this post, I’ll walk you through the main components of the game.

Gameplay

The Game Loop

The core of the game is the main loop, which handles events, updates the game state, and draws everything on the screen.

def main():
    # ... initialization ...

    # game loop
    while (True):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return
        
        screen.fill(color = "black")

        updatable.update(dt)
        for sprite in drawable:
            sprite.draw(screen)

        for asteroid in asteroids:
            if asteroid.check_collisions(player):
                print("Game over!")
                exit(0)
            for shot in shots:
                if asteroid.check_collisions(shot):
                    asteroid.split()
                    shot.kill()

        dt = clock.tick(60) / 1000

        pygame.display.flip()

The Player

The player is represented by a triangle with a circular hitbox that can move and shoot. The Player class handles the player’s movement, rotation, and shooting.

class Player(CircleShape):
    # ...

    def move(self, dt):
        forward = pygame.Vector2(0, 1).rotate(self.rotation)
        self.position += forward * PLAYER_SPEED * dt
    
    def rotate(self, dt):
        self.rotation += PLAYER_TURN_SPEED * dt

    def shoot(self):
        if self.shot_timer < 0:
            shot = Shot(self.position.x, self.position.y)
            shot.velocity = PLAYER_SHOOT_SPEED * pygame.Vector2(0, 1).rotate(self.rotation)
            self.shot_timer = PLAYER_SHOOT_COOLDOWN

Asteroids

The asteroids are represented by circles that move across the screen. When an asteroid is shot, it splits into two smaller asteroids and speeds up, assuming it was above the asteroid’s minimum radius.

class Asteroid(CircleShape):
    # ...

    def split(self):
        self.kill()
        if self.radius < ASTEROID_MIN_RADIUS:
            return

        # spawn two new asteroids
        angle = random.uniform(20, 50)
        
        new_asteroid_1 = Asteroid(self.position.x, self.position.y, self.radius-ASTEROID_MIN_RADIUS)
        new_asteroid_1.velocity = 1.2 * self.velocity.rotate(angle)

        new_asteroid_2 = Asteroid(self.position.x, self.position.y, self.radius-ASTEROID_MIN_RADIUS)
        new_asteroid_2.velocity = 1.2 * self.velocity.rotate(-angle)

Future Work

This is just a simple implementation, and there are many features that could be added, such as:

  • A scoring system
  • Multiple lives and respawning
  • Explosion effects
  • A background image
  • Different weapon types

You can find the full source code for this project here

Credits

This project was created following the “Build an Asteroids Game” tutorial from boot.dev. You can find the original tutorial here.