Space Invaders Game in Python

This tutorial guides you through initializing Pygame, setting up the game screen, and implementing game mechanics such as player movement, enemy generation, shooting bullets, and collision detection. Learn to load assets, handle events, and display scores. By the end of this tutorial, you’ll have a fully functional Space Invaders game.

Prerequisites

First, you need to install pygame if you haven’t already:

pip install pygame

Space Invaders Game Code

Here’s a complete, simple implementation of the Space Invaders game:

import pygame
import random
import math

# Initialize pygame
pygame.init()

# Screen dimensions
screen_width = 800
screen_height = 600

# Colors
black = (0, 0, 0)
white = (255, 255, 255)
red = (255, 0, 0)

# Set up the display
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("Space Invaders")

# Load images
player_img = pygame.image.load('player.png')
enemy_img = pygame.image.load('enemy.png')
bullet_img = pygame.image.load('bullet.png')

# Player
player_x = screen_width // 2 - 32
player_y = screen_height - 100
player_x_change = 0
player_speed = 5

# Enemy
enemy_img_list = []
enemy_x = []
enemy_y = []
enemy_x_change = []
enemy_y_change = []
num_of_enemies = 6

for i in range(num_of_enemies):
    enemy_img_list.append(enemy_img)
    enemy_x.append(random.randint(0, screen_width - 64))
    enemy_y.append(random.randint(50, 150))
    enemy_x_change.append(3)
    enemy_y_change.append(40)

# Bullet
bullet_x = 0
bullet_y = player_y
bullet_x_change = 0
bullet_y_change = 10
bullet_state = "ready"

# Score
score = 0
font = pygame.font.Font('freesansbold.ttf', 32)
text_x = 10
text_y = 10

# Functions
def show_score(x, y):
    score_value = font.render("Score: " + str(score), True, white)
    screen.blit(score_value, (x, y))

def player(x, y):
    screen.blit(player_img, (x, y))

def enemy(x, y, i):
    screen.blit(enemy_img_list[i], (x, y))

def fire_bullet(x, y):
    global bullet_state
    bullet_state = "fire"
    screen.blit(bullet_img, (x + 16, y + 10))

def is_collision(enemy_x, enemy_y, bullet_x, bullet_y):
    distance = math.sqrt(math.pow(enemy_x - bullet_x, 2) + math.pow(enemy_y - bullet_y, 2))
    return distance < 27

# Main game loop
running = True
while running:
    screen.fill(black)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                player_x_change = -player_speed
            if event.key == pygame.K_RIGHT:
                player_x_change = player_speed
            if event.key == pygame.K_SPACE:
                if bullet_state == "ready":
                    bullet_x = player_x
                    fire_bullet(bullet_x, bullet_y)

        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                player_x_change = 0

    player_x += player_x_change
    if player_x <= 0:
        player_x = 0
    elif player_x >= screen_width - 64:
        player_x = screen_width - 64

    for i in range(num_of_enemies):
        enemy_x[i] += enemy_x_change[i]
        if enemy_x[i] <= 0:
            enemy_x_change[i] = 3
            enemy_y[i] += enemy_y_change[i]
        elif enemy_x[i] >= screen_width - 64:
            enemy_x_change[i] = -3
            enemy_y[i] += enemy_y_change[i]

        collision = is_collision(enemy_x[i], enemy_y[i], bullet_x, bullet_y)
        if collision:
            bullet_y = player_y
            bullet_state = "ready"
            score += 1
            enemy_x[i] = random.randint(0, screen_width - 64)
            enemy_y[i] = random.randint(50, 150)

        enemy(enemy_x[i], enemy_y[i], i)

    if bullet_y <= 0:
        bullet_y = player_y
        bullet_state = "ready"
    if bullet_state == "fire":
        fire_bullet(bullet_x, bullet_y)
        bullet_y -= bullet_y_change

    player(player_x, player_y)
    show_score(text_x, text_y)

    pygame.display.update()

pygame.quit()

Explanation:

  1. Initialization: Initializes pygame and sets up screen dimensions and colors.
  2. Assets: Loads images for the player, enemies, and bullets. Make sure to have player.png, enemy.png, and bullet.png in the same directory as your script.
  3. Player: Initializes player position and speed.
  4. Enemies: Initializes multiple enemies with random positions and speeds.
  5. Bullet: Initializes bullet position, speed, and state.
  6. Score: Initializes score and font for displaying the score.
  7. Functions:
    • show_score(x, y): Renders and displays the score on the screen.
    • player(x, y): Draws the player at the given coordinates.
    • enemy(x, y, i): Draws an enemy at the given coordinates.
    • fire_bullet(x, y): Fires a bullet from the player’s position.
    • is_collision(enemy_x, enemy_y, bullet_x, bullet_y): Checks if a bullet has collided with an enemy.
  8. Main Game Loop:
    • Handles events (key presses and releases).
    • Updates player and enemy positions.
    • Fires bullets and checks for collisions.
    • Updates the screen with new positions and scores.

This code provides a basic version of the Space Invaders game. You can enhance it further by adding more features, improving graphics, and implementing levels and sound effects.