Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save moriarty99779/945b9c9f158726582f5c0991a132a60c to your computer and use it in GitHub Desktop.
Save moriarty99779/945b9c9f158726582f5c0991a132a60c to your computer and use it in GitHub Desktop.
Simple Space Invaders using Python and PyGame
import pygame
import random
import math
import os
# Initialize
pygame.init()
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Space Invaders")
# Assets folder
ASSETS = "assets"
# Load images
player_img = pygame.image.load(os.path.join(ASSETS, "player.png"))
enemy_img = pygame.image.load(os.path.join(ASSETS, "enemy.png"))
bullet_img = pygame.image.load(os.path.join(ASSETS, "bullet.png"))
enemy_bullet_img = pygame.image.load(os.path.join(ASSETS, "enemy_bullet.png"))
explosion_imgs = [pygame.image.load(os.path.join(ASSETS, f"explosion{i}.png")) for i in range(1, 5)]
# Load sounds
shoot_sound = pygame.mixer.Sound(os.path.join(ASSETS, "shoot.wav"))
explosion_sound = pygame.mixer.Sound(os.path.join(ASSETS, "explosion.wav"))
game_over_sound = pygame.mixer.Sound(os.path.join(ASSETS, "gameover.wav"))
# Colors
WHITE = (255, 255, 255)
background_color = (10, 10, 30)
font = pygame.font.SysFont("consolas", 28)
# Game Variables
player_x = 370
player_y = 500
player_speed = 5
bullet_x = 0
bullet_y = player_y
bullet_speed = 7
bullet_state = "ready"
score = 0
level = 1
lives = 3
enemy_rows = 3
enemy_cols = 6
enemy_bullets = []
enemy_bullet_speed = 4
enemy_fire_delay = 50 # Lower = more frequent
# Enemies
def spawn_enemies(rows):
enemies = []
for row in range(rows):
for col in range(enemy_cols):
x = 100 + col * 80
y = 50 + row * 60
enemy = {"x": x, "y": y, "x_change": 2, "y_change": 40, "alive": True}
enemies.append(enemy)
return enemies
enemies = spawn_enemies(enemy_rows)
# Explosion animation
explosions = []
def show_explosion(x, y):
explosions.append({"x": x, "y": y, "frame": 0})
def draw_explosions():
for e in explosions[:]:
screen.blit(explosion_imgs[e["frame"] // 5], (e["x"], e["y"]))
e["frame"] += 1
if e["frame"] >= 20:
explosions.remove(e)
# Helper Functions
def is_collision(x1, y1, x2, y2, threshold=27):
return math.hypot(x2 - x1, y2 - y1) < threshold
def fire_bullet():
global bullet_state, bullet_x, bullet_y
bullet_state = "fire"
bullet_x = player_x
bullet_y = player_y
shoot_sound.play()
def draw_enemies():
for enemy in enemies:
if enemy["alive"]:
screen.blit(enemy_img, (enemy["x"], enemy["y"]))
def fire_enemy_bullet(enemy):
if random.randint(0, enemy_fire_delay) == 0:
bullet = {"x": enemy["x"] + 24, "y": enemy["y"] + 32}
enemy_bullets.append(bullet)
def game_over():
game_over_sound.play()
msg = font.render("GAME OVER", True, WHITE)
screen.blit(msg, (WIDTH//2 - 100, HEIGHT//2 - 20))
pygame.display.update()
pygame.time.wait(3000)
pygame.quit()
exit()
# Main loop
clock = pygame.time.Clock()
running = True
while running:
screen.fill(background_color)
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# Keypress
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
player_x -= player_speed
if keys[pygame.K_RIGHT]:
player_x += player_speed
if keys[pygame.K_SPACE] and bullet_state == "ready":
fire_bullet()
# Player bounds
player_x = max(0, min(player_x, WIDTH - 64))
# Bullet movement
if bullet_state == "fire":
screen.blit(bullet_img, (bullet_x + 16, bullet_y))
bullet_y -= bullet_speed
if bullet_y <= 0:
bullet_state = "ready"
# Enemy logic
enemy_direction_change = False
for enemy in enemies:
if enemy["alive"]:
enemy["x"] += enemy["x_change"]
if enemy["x"] <= 0 or enemy["x"] >= WIDTH - 64:
enemy["x_change"] *= -1
enemy_direction_change = True
fire_enemy_bullet(enemy)
# Collision with bullet
if bullet_state == "fire" and is_collision(bullet_x, bullet_y, enemy["x"], enemy["y"]):
enemy["alive"] = False
show_explosion(enemy["x"], enemy["y"])
explosion_sound.play()
score += 10
bullet_state = "ready"
# Check game over condition
if enemy["y"] > player_y - 40:
game_over()
if enemy_direction_change:
for enemy in enemies:
enemy["y"] += enemy["y_change"]
# Enemy bullets
for eb in enemy_bullets[:]:
screen.blit(enemy_bullet_img, (eb["x"], eb["y"]))
eb["y"] += enemy_bullet_speed
if eb["y"] > HEIGHT:
enemy_bullets.remove(eb)
elif is_collision(eb["x"], eb["y"], player_x, player_y, 30):
show_explosion(player_x, player_y)
explosion_sound.play()
enemy_bullets.remove(eb)
lives -= 1
if lives <= 0:
game_over()
# Level progression
if all(not e["alive"] for e in enemies):
level += 1
enemy_rows += 1
enemy_fire_delay = max(10, enemy_fire_delay - 5)
enemies = spawn_enemies(enemy_rows)
# Draw player and enemies
screen.blit(player_img, (player_x, player_y))
draw_enemies()
draw_explosions()
# Score and lives
score_text = font.render(f"Score: {score} Lives: {lives} Level: {level}", True, WHITE)
screen.blit(score_text, (10, 10))
pygame.display.update()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment