commit 55bd37987ef06b6310bc97f8cc9ec2bbb4498828 Author: Michael Howard Date: Thu Apr 9 09:39:28 2026 -0500 first commit diff --git a/CosmicPixels.wav b/CosmicPixels.wav new file mode 100644 index 0000000..0a1901a Binary files /dev/null and b/CosmicPixels.wav differ diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/asteroid.png b/asteroid.png new file mode 100644 index 0000000..011607f Binary files /dev/null and b/asteroid.png differ diff --git a/boss2.jpg b/boss2.jpg new file mode 100644 index 0000000..508026d Binary files /dev/null and b/boss2.jpg differ diff --git a/boss_level1.png b/boss_level1.png new file mode 100644 index 0000000..9e48004 Binary files /dev/null and b/boss_level1.png differ diff --git a/boss_level2.png b/boss_level2.png new file mode 100644 index 0000000..fa44c3d Binary files /dev/null and b/boss_level2.png differ diff --git a/boss_level3.png b/boss_level3.png new file mode 100644 index 0000000..90262b3 Binary files /dev/null and b/boss_level3.png differ diff --git a/credits.wav b/credits.wav new file mode 100644 index 0000000..430f414 Binary files /dev/null and b/credits.wav differ diff --git a/enemy_ship.png b/enemy_ship.png new file mode 100644 index 0000000..c18cbaa Binary files /dev/null and b/enemy_ship.png differ diff --git a/explosion.wav b/explosion.wav new file mode 100644 index 0000000..44870cd Binary files /dev/null and b/explosion.wav differ diff --git a/heal.jpg b/heal.jpg new file mode 100644 index 0000000..269e2c5 Binary files /dev/null and b/heal.jpg differ diff --git a/laser_shoot.wav b/laser_shoot.wav new file mode 100644 index 0000000..38246e6 Binary files /dev/null and b/laser_shoot.wav differ diff --git a/layer.png b/layer.png new file mode 100644 index 0000000..5d080d7 Binary files /dev/null and b/layer.png differ diff --git a/level1.wav b/level1.wav new file mode 100644 index 0000000..1bc53c7 Binary files /dev/null and b/level1.wav differ diff --git a/level2.wav b/level2.wav new file mode 100644 index 0000000..8c2917c Binary files /dev/null and b/level2.wav differ diff --git a/level3.wav b/level3.wav new file mode 100644 index 0000000..0dba012 Binary files /dev/null and b/level3.wav differ diff --git a/main.py b/main.py new file mode 100644 index 0000000..5ce66ba --- /dev/null +++ b/main.py @@ -0,0 +1,1161 @@ +import pygame +import random +import sys + +# --- Initialize Pygame and Mixer --- +pygame.init() +pygame.mixer.init() + +# --- Screen Settings --- +SCREEN_WIDTH = 800 +SCREEN_HEIGHT = 600 +screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) +pygame.display.set_caption("Cosmic Pixels") +clock = pygame.time.Clock() + +# --- Colors --- +BLACK = (0, 0, 0) +WHITE = (255, 255, 255) +CYAN = (0, 255, 255) +YELLOW = (255, 255, 0) +PLAYER_COLOR = (0, 200, 255) # Fallback color +RED = (255, 0, 0) +GREEN = (0, 255, 0) +ORANGE = (255, 165, 0) + +# --- Load Assets (Font and Music) --- +try: + title_font = pygame.font.Font('pixel_font.ttf', 72) + prompt_font = pygame.font.Font('pixel_font.ttf', 30) + score_font = pygame.font.Font('pixel_font.ttf', 24) +except FileNotFoundError: + title_font = pygame.font.SysFont('Consolas', 72, bold=True) + prompt_font = pygame.font.SysFont('Consolas', 30) + score_font = pygame.font.SysFont('Consolas', 24) + + +# --- Load Sound Effects --- +try: + shoot_sound = pygame.mixer.Sound('laser_shoot.wav') + explosion_sound = pygame.mixer.Sound('explosion.wav') + death_sound = pygame.mixer.Sound('player_death.wav') + print("Sound effects loaded.") +except pygame.error: + print("Warning: One or more sound effect files are missing.") + shoot_sound = None + explosion_sound = None + death_sound = None + +# --- Starfield Setup --- +stars = [] +for _ in range(200): + x = random.randrange(0, SCREEN_WIDTH) + y = random.randrange(0, SCREEN_HEIGHT) + speed = random.randint(1, 3) + stars.append([x, y, speed]) + +# --- Bullet Class --- +class Bullet: + def __init__(self, x, y, dx, dy): + self.rect = pygame.Rect(x, y, 10, 5) + self.dx = dx + self.dy = dy + + def update(self): + self.rect.x += self.dx + self.rect.y += self.dy + +# --- Letter Class for Animation --- +class Letter: + def __init__(self, char, font, color, start_pos, end_pos, anim_duration=0.5): + self.surface = font.render(char, True, color) + self.start_pos = pygame.Vector2(start_pos) + self.end_pos = pygame.Vector2(end_pos) + self.current_pos = pygame.Vector2(start_pos) + self.anim_duration_ms = anim_duration * 1000 + self.anim_start_time = 0 + self.is_animating = False + self.is_finished = False + + def start_animation(self): + self.is_animating = True + self.anim_start_time = pygame.time.get_ticks() + + def update(self): + if not self.is_animating: return + elapsed_time = pygame.time.get_ticks() - self.anim_start_time + progress = min(elapsed_time / self.anim_duration_ms, 1.0) + progress = 1 - (1 - progress) ** 3 + self.current_pos = self.start_pos.lerp(self.end_pos, progress) + if progress >= 1.0: + self.is_animating = False + self.is_finished = True + + def draw(self, screen): + screen.blit(self.surface, self.current_pos) + +# --- Game Loop Function (Level 1) --- +def game_loop(): + """This function runs the main gameplay for Level 1.""" + + pygame.mixer.music.stop() + try: + pygame.mixer.music.load('level1.wav') + pygame.mixer.music.play(-1) + except pygame.error: + print("Warning: Music file 'level1.wav' not found.") + + try: + player_image = pygame.image.load('layer.png').convert_alpha() + player_image = pygame.transform.scale(player_image, (80, 40)) + except pygame.error: + player_image = None + player_rect = player_image.get_rect() if player_image else pygame.Rect(0, 0, 80, 40) + player_rect.x = 50 + player_rect.centery = SCREEN_HEIGHT / 2 + PLAYER_SPEED = 5 + player_health = 100 + max_health = 100 + player_dead = False + death_timer_start = 0 + + score = 0 + kill_count = 0 + kills_for_boss = 20 + boss_fight_active = False + boss_defeated = False + + player_bullets = [] + enemy_bullets = [] + boss_bullets = [] + + try: + enemy_image = pygame.image.load('enemy_ship.png').convert_alpha() + enemy_image = pygame.transform.scale(enemy_image, (50, 50)) + except pygame.error: + enemy_image = None + enemies = [] + ENEMY_SPEED = 3 + ENEMY_SPAWN_EVENT = pygame.USEREVENT + 1 + pygame.time.set_timer(ENEMY_SPAWN_EVENT, 1000) + + try: + boss_image = pygame.image.load('boss_level1.png').convert_alpha() + boss_image = pygame.transform.scale(boss_image, (150, 100)) + except pygame.error: + boss_image = None + boss_rect = None + boss_health = 200 + boss_max_health = 200 + boss_speed = 2 + boss_direction = 1 + boss_is_entering = False + + thruster_length = 10 + + running = True + while running: + for event in pygame.event.get(): + if event.type == pygame.QUIT: + pygame.quit() + sys.exit() + + if event.type == pygame.KEYDOWN and not boss_defeated and not player_dead: + if event.key == pygame.K_SPACE: + player_bullets.append(Bullet(player_rect.right, player_rect.centery - 2, 10, 0)) + if shoot_sound: shoot_sound.play() + + if event.type == ENEMY_SPAWN_EVENT and not boss_fight_active: + enemy_y_pos = random.randint(50, SCREEN_HEIGHT - 50) + enemy_rect = enemy_image.get_rect(midleft=(SCREEN_WIDTH + 20, enemy_y_pos)) if enemy_image else pygame.Rect(SCREEN_WIDTH + 20, enemy_y_pos, 50, 50) + enemies.append(enemy_rect) + + if not boss_defeated and not player_dead: + keys = pygame.key.get_pressed() + is_moving_forward = False + if keys[pygame.K_LEFT]: player_rect.x -= PLAYER_SPEED + if keys[pygame.K_RIGHT]: + player_rect.x += PLAYER_SPEED + is_moving_forward = True + if keys[pygame.K_UP]: player_rect.y -= PLAYER_SPEED + if keys[pygame.K_DOWN]: player_rect.y += PLAYER_SPEED + thruster_length = 25 if is_moving_forward else 10 + + if not player_dead: + if player_rect.left < 0: player_rect.left = 0 + if player_rect.right > SCREEN_WIDTH and not boss_defeated: player_rect.right = SCREEN_WIDTH + if player_rect.top < 0: player_rect.top = 0 + if player_rect.bottom > SCREEN_HEIGHT: player_rect.bottom = SCREEN_HEIGHT + + for bullet in player_bullets: bullet.update() + for bullet in enemy_bullets: bullet.x -= 10 + for bullet in boss_bullets: bullet.x -= 12 + for enemy in enemies: + enemy.x -= ENEMY_SPEED + if random.randint(0, 150) == 1: + enemy_bullet = pygame.Rect(enemy.left, enemy.centery - 2, 10, 5) + enemy_bullets.append(enemy_bullet) + + if not player_dead: + for bullet in player_bullets[:]: + bullet_removed = False + for enemy in enemies[:]: + if bullet.rect.colliderect(enemy): + enemies.remove(enemy) + player_bullets.remove(bullet) + score += 10 + kill_count += 1 + if explosion_sound: explosion_sound.play() + bullet_removed = True + break + if bullet_removed: continue + + for enemy in enemies[:]: + if player_rect.colliderect(enemy): + enemies.remove(enemy) + player_health -= 25 + if explosion_sound: explosion_sound.play() + + for bullet in enemy_bullets[:] + boss_bullets[:]: + if player_rect.colliderect(bullet): + if bullet in enemy_bullets: enemy_bullets.remove(bullet) + if bullet in boss_bullets: boss_bullets.remove(bullet) + player_health -= 10 + + if boss_fight_active and boss_rect and not boss_defeated: + if boss_is_entering: + entry_target_x = SCREEN_WIDTH - boss_rect.width - 20 + if boss_rect.x > entry_target_x: boss_rect.x -= 5 + else: boss_is_entering = False + else: + boss_rect.y += boss_speed * boss_direction + if boss_rect.top <= 0 or boss_rect.bottom >= SCREEN_HEIGHT: boss_direction *= -1 + if random.randint(0, 40) == 1: + boss_bullet = pygame.Rect(boss_rect.left, boss_rect.centery, 15, 8) + boss_bullets.append(boss_bullet) + + for bullet in player_bullets[:]: + if bullet.rect.colliderect(boss_rect): + player_bullets.remove(bullet) + boss_health -= 5 + if boss_health <= 0: + boss_defeated = True + if explosion_sound: explosion_sound.play() + pygame.mixer.music.fadeout(2000) + boss_rect = None + enemy_bullets.clear() + boss_bullets.clear() + break + + if kill_count >= kills_for_boss and not boss_fight_active: + boss_fight_active = True + boss_is_entering = True + enemies.clear() + pygame.time.set_timer(ENEMY_SPAWN_EVENT, 0) + print("BOSS FIGHT STARTED!") + boss_rect = boss_image.get_rect(midleft=(SCREEN_WIDTH, SCREEN_HEIGHT / 2)) if boss_image else pygame.Rect(SCREEN_WIDTH, SCREEN_HEIGHT/2 - 50, 150, 100) + + if player_health <= 0 and not player_dead: + player_dead = True + if death_sound: death_sound.play() + death_timer_start = pygame.time.get_ticks() + pygame.mixer.music.stop() + + if player_dead: + if pygame.time.get_ticks() - death_timer_start > 2000: + fade_surface = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT)) + fade_surface.fill(BLACK) + for alpha in range(0, 255, 5): + fade_surface.set_alpha(alpha) + screen.blit(fade_surface, (0,0)) + pygame.display.flip() + pygame.time.delay(30) + + died_text = title_font.render("YOU DIED", True, RED) + died_rect = died_text.get_rect(center=(SCREEN_WIDTH/2, SCREEN_HEIGHT/2)) + screen.blit(died_text, died_rect) + pygame.display.flip() + pygame.time.wait(3000) + return + + if boss_defeated: + player_rect.x += PLAYER_SPEED + if player_rect.left > SCREEN_WIDTH: + fade_surface = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT)) + fade_surface.fill(BLACK) + for alpha in range(0, 255, 5): + fade_surface.set_alpha(alpha) + screen.blit(fade_surface, (0,0)) + pygame.display.flip() + pygame.time.delay(30) + + level2_text = title_font.render("LEVEL 2", True, WHITE) + level2_rect = level2_text.get_rect(center=(SCREEN_WIDTH/2, SCREEN_HEIGHT/2)) + screen.blit(level2_text, level2_rect) + pygame.display.flip() + pygame.time.wait(3000) + level_2_loop(player_health, score) + running = False + + screen.fill(BLACK) + for star in stars: + star[0] -= star[2] + if star[0] < 0: star[0] = SCREEN_WIDTH; star[1] = random.randrange(0, SCREEN_HEIGHT) + pygame.draw.rect(screen, WHITE, (star[0], star[1], star[2], star[2])) + + player_bullets = [b for b in player_bullets if b.rect.left < SCREEN_WIDTH] + for bullet in player_bullets: pygame.draw.rect(screen, YELLOW, bullet.rect) + + enemy_bullets = [b for b in enemy_bullets if b.right > 0] + for bullet in enemy_bullets: pygame.draw.rect(screen, RED, bullet) + + boss_bullets = [b for b in boss_bullets if b.right > 0] + for bullet in boss_bullets: pygame.draw.rect(screen, RED, bullet) + + enemies = [e for e in enemies if e.right > 0] + for enemy in enemies: + if enemy_image: screen.blit(enemy_image, enemy) + else: pygame.draw.rect(screen, RED, enemy) + + if boss_rect: + if boss_image: screen.blit(boss_image, boss_rect) + else: pygame.draw.rect(screen, CYAN, boss_rect) + + if not player_dead: + if boss_defeated: + thruster_length = 25 # Keep thrust on during fly-off + thruster_rect = pygame.Rect(player_rect.left - thruster_length, player_rect.centery - 5, thruster_length, 10) + pygame.draw.rect(screen, ORANGE, thruster_rect) + if player_image: screen.blit(player_image, player_rect) + else: pygame.draw.rect(screen, PLAYER_COLOR, player_rect) + + health_bar_width = max(0, (player_health / max_health) * 200) + pygame.draw.rect(screen, RED, (10, 10, 200, 20)) + pygame.draw.rect(screen, GREEN, (10, 10, health_bar_width, 20)) + + score_text = score_font.render(f"Score: {score}", True, WHITE) + screen.blit(score_text, score_text.get_rect(center=(SCREEN_WIDTH / 2, 20))) + + if boss_fight_active and not boss_defeated and boss_rect: + boss_health_width = max(0, (boss_health / boss_max_health) * 200) + pygame.draw.rect(screen, RED, (SCREEN_WIDTH - 210, 10, 200, 20)) + pygame.draw.rect(screen, GREEN, (SCREEN_WIDTH - 210, 10, boss_health_width, 20)) + + pygame.display.flip() + clock.tick(60) + +def level_2_loop(player_health, score): + pygame.mixer.music.stop() + try: + pygame.mixer.music.load('level2.wav') + pygame.mixer.music.play(-1) + except pygame.error: + print("Warning: Music file 'level2.wav' not found.") + + try: + player_image = pygame.image.load('layer.png').convert_alpha() + player_image = pygame.transform.scale(player_image, (80, 40)) + except pygame.error: + player_image = None + player_rect = player_image.get_rect() if player_image else pygame.Rect(0, 0, 80, 40) + player_rect.x = 50 + player_rect.centery = SCREEN_HEIGHT / 2 + PLAYER_SPEED = 5 + max_health = 100 + player_dead = False + death_timer_start = 0 + + player_has_triple_shot = False + powerup_spawned = False + powerup_active_start_time = 0 + POWERUP_DURATION = 30000 + try: + powerup_image = pygame.image.load('powerup_triple_shot.png').convert_alpha() + powerup_image = pygame.transform.scale(powerup_image, (40, 40)) + except pygame.error: + powerup_image = None + powerup_rect = None + + try: + mine_image = pygame.image.load('space_mine.png').convert_alpha() + mine_image = pygame.transform.scale(mine_image, (40, 40)) + except pygame.error: + mine_image = None + mines = [] + MINE_SPAWN_EVENT = pygame.USEREVENT + 2 + pygame.time.set_timer(MINE_SPAWN_EVENT, 2000) + + try: + enemy_image = pygame.image.load('enemy_ship.png').convert_alpha() + enemy_image = pygame.transform.scale(enemy_image, (50, 50)) + except pygame.error: + enemy_image = None + enemies = [] + ENEMY_SPEED_L2 = 4 + ENEMY_SPAWN_EVENT_L2 = pygame.USEREVENT + 3 + pygame.time.set_timer(ENEMY_SPAWN_EVENT_L2, 800) + + kill_count = 0 + kills_for_powerup = 10 + kills_for_boss = 40 + + boss_fight_active = False + boss_defeated = False + try: + boss_image = pygame.image.load('boss_level2.png').convert_alpha() + boss_image = pygame.transform.scale(boss_image, (170, 120)) + except pygame.error: + print("Warning: 'boss_level2.png' not found.") + boss_image = None + boss_rect = None + boss_health = 400 + boss_max_health = 400 + boss_speed = 3 + boss_direction = 1 + boss_is_entering = False + + player_bullets = [] + enemy_bullets = [] + boss_bullets = [] + thruster_length = 10 + + running = True + while running: + for event in pygame.event.get(): + if event.type == pygame.QUIT: + pygame.quit() + sys.exit() + + if event.type == pygame.KEYDOWN and not boss_defeated and not player_dead: + if event.key == pygame.K_SPACE: + if player_has_triple_shot: + player_bullets.append(Bullet(player_rect.right, player_rect.centery - 2, 10, -2)) + player_bullets.append(Bullet(player_rect.right, player_rect.centery - 2, 10, 0)) + player_bullets.append(Bullet(player_rect.right, player_rect.centery - 2, 10, 2)) + else: + player_bullets.append(Bullet(player_rect.right, player_rect.centery - 2, 10, 0)) + if shoot_sound: shoot_sound.play() + + if event.type == MINE_SPAWN_EVENT and not boss_fight_active: + mine_y = random.randint(20, SCREEN_HEIGHT - 20) + mine_rect = mine_image.get_rect(center=(SCREEN_WIDTH + 20, mine_y)) if mine_image else pygame.Rect(SCREEN_WIDTH + 20, mine_y, 40, 40) + mines.append(mine_rect) + + if event.type == ENEMY_SPAWN_EVENT_L2 and not boss_fight_active: + enemy_y_pos = random.randint(50, SCREEN_HEIGHT - 50) + enemy_rect = enemy_image.get_rect(midleft=(SCREEN_WIDTH + 20, enemy_y_pos)) if enemy_image else pygame.Rect(SCREEN_WIDTH + 20, enemy_y_pos, 50, 50) + enemies.append(enemy_rect) + + if not boss_defeated and not player_dead: + keys = pygame.key.get_pressed() + is_moving_forward = False + if keys[pygame.K_LEFT]: player_rect.x -= PLAYER_SPEED + if keys[pygame.K_RIGHT]: + player_rect.x += PLAYER_SPEED + is_moving_forward = True + if keys[pygame.K_UP]: player_rect.y -= PLAYER_SPEED + if keys[pygame.K_DOWN]: player_rect.y += PLAYER_SPEED + thruster_length = 25 if is_moving_forward else 10 + + if not player_dead: + if player_rect.left < 0: player_rect.left = 0 + if player_rect.right > SCREEN_WIDTH and not boss_defeated: player_rect.right = SCREEN_WIDTH + if player_rect.top < 0: player_rect.top = 0 + if player_rect.bottom > SCREEN_HEIGHT: player_rect.bottom = SCREEN_HEIGHT + + if kill_count >= kills_for_powerup and not powerup_spawned: + powerup_spawned = True + powerup_rect = powerup_image.get_rect(center=(SCREEN_WIDTH + 30, SCREEN_HEIGHT / 2)) if powerup_image else pygame.Rect(SCREEN_WIDTH + 30, SCREEN_HEIGHT / 2, 40, 40) + + if player_has_triple_shot: + elapsed_time = pygame.time.get_ticks() - powerup_active_start_time + if elapsed_time > POWERUP_DURATION: + player_has_triple_shot = False + + for bullet in player_bullets: bullet.update() + for bullet in enemy_bullets: bullet.x -= 10 + for bullet in boss_bullets: bullet.update() + for enemy in enemies: + enemy.x -= ENEMY_SPEED_L2 + if random.randint(0, 120) == 1: + enemy_bullet = pygame.Rect(enemy.left, enemy.centery - 2, 10, 5) + enemy_bullets.append(enemy_bullet) + for mine in mines: mine.x -= 2 + if powerup_rect: powerup_rect.x -= 3 + + if not player_dead: + for mine in mines[:]: + if player_rect.colliderect(mine): + mines.remove(mine) + player_health -= 20 + if explosion_sound: explosion_sound.play() + + for bullet in player_bullets[:]: + bullet_removed = False + for enemy in enemies[:]: + if bullet.rect.colliderect(enemy): + enemies.remove(enemy) + player_bullets.remove(bullet) + score += 15 + kill_count += 1 + if explosion_sound: explosion_sound.play() + bullet_removed = True + break + if bullet_removed: continue + + for enemy in enemies[:]: + if player_rect.colliderect(enemy): + enemies.remove(enemy) + player_health -= 25 + if explosion_sound: explosion_sound.play() + + for bullet in enemy_bullets[:] + [b.rect for b in boss_bullets]: + if player_rect.colliderect(bullet): + if isinstance(bullet, pygame.Rect) and bullet in enemy_bullets: + enemy_bullets.remove(bullet) + else: + for b in boss_bullets[:]: + if b.rect == bullet: + boss_bullets.remove(b) + break + player_health -= 10 + + if powerup_rect and player_rect.colliderect(powerup_rect): + player_has_triple_shot = True + powerup_active_start_time = pygame.time.get_ticks() + powerup_rect = None + + if kill_count >= kills_for_boss and not boss_fight_active: + boss_fight_active = True + boss_is_entering = True + enemies.clear() + mines.clear() + pygame.time.set_timer(ENEMY_SPAWN_EVENT_L2, 0) + pygame.time.set_timer(MINE_SPAWN_EVENT, 0) + boss_rect = boss_image.get_rect(midleft=(SCREEN_WIDTH, SCREEN_HEIGHT / 2)) if boss_image else pygame.Rect(SCREEN_WIDTH, SCREEN_HEIGHT/2-60, 170, 120) + + if boss_fight_active and boss_rect and not boss_defeated: + if boss_is_entering: + entry_target_x = SCREEN_WIDTH - boss_rect.width - 20 + if boss_rect.x > entry_target_x: + boss_rect.x -= 5 + else: + boss_is_entering = False + else: + boss_rect.y += boss_speed * boss_direction + if boss_rect.top <= 0 or boss_rect.bottom >= SCREEN_HEIGHT: + boss_direction *= -1 + if random.randint(0, 50) == 1: + boss_bullets.append(Bullet(boss_rect.left, boss_rect.centery, -12, -2)) + boss_bullets.append(Bullet(boss_rect.left, boss_rect.centery, -12, 0)) + boss_bullets.append(Bullet(boss_rect.left, boss_rect.centery, -12, 2)) + + for bullet in player_bullets[:]: + if bullet.rect.colliderect(boss_rect): + player_bullets.remove(bullet) + boss_health -= 5 + if boss_health <= 0: + boss_defeated = True + if explosion_sound: explosion_sound.play() + pygame.mixer.music.fadeout(2000) + boss_rect = None + break + + if player_health <= 0 and not player_dead: + player_dead = True + if death_sound: death_sound.play() + death_timer_start = pygame.time.get_ticks() + pygame.mixer.music.stop() + + if player_dead: + if pygame.time.get_ticks() - death_timer_start > 2000: + fade_surface = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT)) + fade_surface.fill(BLACK) + for alpha in range(0, 255, 5): + fade_surface.set_alpha(alpha) + screen.blit(fade_surface, (0,0)) + pygame.display.flip() + pygame.time.delay(30) + + died_text = title_font.render("YOU DIED", True, RED) + died_rect = died_text.get_rect(center=(SCREEN_WIDTH/2, SCREEN_HEIGHT/2)) + screen.blit(died_text, died_rect) + pygame.display.flip() + pygame.time.wait(3000) + return + + if boss_defeated: + player_rect.x += PLAYER_SPEED + if player_rect.left > SCREEN_WIDTH: + fade_surface = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT)) + fade_surface.fill(BLACK) + for alpha in range(0, 255, 4): + fade_surface.set_alpha(alpha) + screen.blit(fade_surface, (0,0)) + pygame.display.flip() + pygame.time.delay(30) + + level3_text = title_font.render("LEVEL 3", True, WHITE) + level3_rect = level3_text.get_rect(center=(SCREEN_WIDTH/2, SCREEN_HEIGHT/2)) + screen.blit(level3_text, level3_rect) + pygame.display.flip() + pygame.time.wait(3000) + level_3_loop(player_health, score) + running = False + + screen.fill(BLACK) + for star in stars: + star[0] -= star[2] + if star[0] < 0: star[0] = SCREEN_WIDTH; star[1] = random.randrange(0, SCREEN_HEIGHT) + pygame.draw.rect(screen, WHITE, (star[0], star[1], star[2], star[2])) + + for bullet in player_bullets: pygame.draw.rect(screen, YELLOW, bullet.rect) + for bullet in enemy_bullets: pygame.draw.rect(screen, RED, bullet) + for bullet in boss_bullets: pygame.draw.rect(screen, RED, bullet.rect) + + for enemy in enemies: + if enemy_image: screen.blit(enemy_image, enemy) + else: pygame.draw.rect(screen, RED, enemy) + + for mine in mines: + if mine_image: screen.blit(mine_image, mine) + else: pygame.draw.rect(screen, RED, mine) + + if powerup_rect: + if powerup_image: screen.blit(powerup_image, powerup_rect) + else: pygame.draw.rect(screen, CYAN, powerup_rect) + + if boss_rect: + if boss_image: screen.blit(boss_image, boss_rect) + else: pygame.draw.rect(screen, CYAN, boss_rect) + + if not player_dead: + if boss_defeated: + thruster_length = 25 + thruster_rect = pygame.Rect(player_rect.left - thruster_length, player_rect.centery - 5, thruster_length, 10) + pygame.draw.rect(screen, ORANGE, thruster_rect) + if player_image: screen.blit(player_image, player_rect) + else: pygame.draw.rect(screen, PLAYER_COLOR, player_rect) + + health_bar_width = max(0, (player_health / max_health) * 200) + pygame.draw.rect(screen, RED, (10, 10, 200, 20)) + pygame.draw.rect(screen, GREEN, (10, 10, health_bar_width, 20)) + score_text = score_font.render(f"Score: {score}", True, WHITE) + screen.blit(score_text, score_text.get_rect(center=(SCREEN_WIDTH / 2, 20))) + level_text = score_font.render("Level 2", True, WHITE) + screen.blit(level_text, level_text.get_rect(topright=(SCREEN_WIDTH - 10, 10))) + + if player_has_triple_shot: + powerup_icon = pygame.transform.scale(powerup_image, (20, 20)) if powerup_image else None + if powerup_icon: screen.blit(powerup_icon, (10, 35)) + elapsed_time = pygame.time.get_ticks() - powerup_active_start_time + remaining_ratio = 1 - (elapsed_time / POWERUP_DURATION) + timer_bar_width = max(0, remaining_ratio * 175) + pygame.draw.rect(screen, RED, (35, 35, 175, 20)) + pygame.draw.rect(screen, YELLOW, (35, 35, timer_bar_width, 20)) + + if boss_fight_active and not boss_defeated and boss_rect: + boss_health_width = max(0, (boss_health / boss_max_health) * 200) + pygame.draw.rect(screen, RED, (SCREEN_WIDTH - 210, 10, 200, 20)) + pygame.draw.rect(screen, GREEN, (SCREEN_WIDTH - 210, 10, boss_health_width, 20)) + + pygame.display.flip() + clock.tick(60) + +def level_3_loop(player_health, score, cheat_mode=False): + pygame.mixer.music.stop() + try: + pygame.mixer.music.load('level3.wav') + pygame.mixer.music.play(-1) + except pygame.error: + print("Warning: Music file 'level3.wav' not found.") + + try: + player_image = pygame.image.load('layer.png').convert_alpha() + player_image = pygame.transform.scale(player_image, (80, 40)) + except pygame.error: + player_image = None + player_rect = player_image.get_rect() if player_image else pygame.Rect(0, 0, 80, 40) + player_rect.x = 50 + player_rect.centery = SCREEN_HEIGHT / 2 + PLAYER_SPEED = 5 + max_health = 100 + player_dead = False + death_timer_start = 0 + if cheat_mode: player_health = 999999 + + player_has_triple_shot = False + powerup_spawned = False + powerup_active_start_time = 0 + POWERUP_DURATION = 30000 + + try: + powerup_image = pygame.image.load('powerup_triple_shot.png').convert_alpha() + powerup_image = pygame.transform.scale(powerup_image, (40, 40)) + except pygame.error: + powerup_image = None + powerup_rect = None + + heal_powerup_spawned = False + try: + heal_image = pygame.image.load('powerup_heal.png').convert_alpha() + heal_image = pygame.transform.scale(heal_image, (40, 40)) + except pygame.error: + heal_image = None + heal_rect = None + + try: + asteroid_image = pygame.image.load('asteroid.png').convert_alpha() + except pygame.error: + asteroid_image = None + asteroids = [] + ASTEROID_SPAWN_EVENT = pygame.USEREVENT + 4 + pygame.time.set_timer(ASTEROID_SPAWN_EVENT, 1500) + + try: + enemy_image = pygame.image.load('enemy_ship.png').convert_alpha() + enemy_image = pygame.transform.scale(enemy_image, (50, 50)) + except pygame.error: + enemy_image = None + enemies = [] + ENEMY_SPEED_L3 = 5 + ENEMY_SPAWN_EVENT_L3 = pygame.USEREVENT + 5 + pygame.time.set_timer(ENEMY_SPAWN_EVENT_L3, 700) + + kill_count = 0 + kills_for_powerup = 15 + kills_for_heal = 30 + kills_for_boss = 50 + + boss_fight_active = False + boss_defeated = False + try: + boss_image = pygame.image.load('boss_level3.png').convert_alpha() + boss_image = pygame.transform.scale(boss_image, (200, 150)) + except pygame.error: + boss_image = None + boss_rect = None + boss_health = 600 + boss_max_health = 600 + boss_speed = 4 + boss_direction = 1 + boss_is_entering = False + + player_bullets = [] + enemy_bullets = [] + boss_bullets = [] + thruster_length = 10 + + running = True + while running: + for event in pygame.event.get(): + if event.type == pygame.QUIT: + pygame.quit() + sys.exit() + + if event.type == pygame.KEYDOWN and not boss_defeated and not player_dead: + if event.key == pygame.K_SPACE: + if player_has_triple_shot: + player_bullets.append(Bullet(player_rect.right, player_rect.centery - 2, 10, -2)) + player_bullets.append(Bullet(player_rect.right, player_rect.centery - 2, 10, 0)) + player_bullets.append(Bullet(player_rect.right, player_rect.centery - 2, 10, 2)) + else: + player_bullets.append(Bullet(player_rect.right, player_rect.centery - 2, 10, 0)) + if shoot_sound: shoot_sound.play() + + if event.type == ASTEROID_SPAWN_EVENT and not boss_fight_active: + size = random.randint(30, 60) + asteroid_y = random.randint(0, SCREEN_HEIGHT - size) + asteroid_rect = pygame.Rect(SCREEN_WIDTH + size, asteroid_y, size, size) + asteroids.append({'rect': asteroid_rect, 'speed': random.randint(2, 4)}) + + if event.type == ENEMY_SPAWN_EVENT_L3 and not boss_fight_active: + enemy_y_pos = random.randint(50, SCREEN_HEIGHT - 50) + enemy_rect = enemy_image.get_rect(midleft=(SCREEN_WIDTH + 20, enemy_y_pos)) if enemy_image else pygame.Rect(SCREEN_WIDTH + 20, enemy_y_pos, 50, 50) + enemies.append(enemy_rect) + + if not boss_defeated and not player_dead: + keys = pygame.key.get_pressed() + is_moving_forward = False + if keys[pygame.K_LEFT]: player_rect.x -= PLAYER_SPEED + if keys[pygame.K_RIGHT]: + player_rect.x += PLAYER_SPEED + is_moving_forward = True + if keys[pygame.K_UP]: player_rect.y -= PLAYER_SPEED + if keys[pygame.K_DOWN]: player_rect.y += PLAYER_SPEED + thruster_length = 25 if is_moving_forward else 10 + + if not player_dead: + if player_rect.left < 0: player_rect.left = 0 + if player_rect.right > SCREEN_WIDTH and not boss_defeated: player_rect.right = SCREEN_WIDTH + if player_rect.top < 0: player_rect.top = 0 + if player_rect.bottom > SCREEN_HEIGHT: player_rect.bottom = SCREEN_HEIGHT + + if kill_count >= kills_for_powerup and not powerup_spawned: + powerup_spawned = True + powerup_rect = powerup_image.get_rect(center=(SCREEN_WIDTH + 30, SCREEN_HEIGHT / 2)) if powerup_image else pygame.Rect(SCREEN_WIDTH + 30, SCREEN_HEIGHT / 2, 40, 40) + + if kill_count >= kills_for_heal and not heal_powerup_spawned: + heal_powerup_spawned = True + heal_rect = heal_image.get_rect(center=(SCREEN_WIDTH + 30, SCREEN_HEIGHT / 3)) if heal_image else pygame.Rect(SCREEN_WIDTH+30, SCREEN_HEIGHT/3, 40, 40) + + if player_has_triple_shot: + elapsed_time = pygame.time.get_ticks() - powerup_active_start_time + if elapsed_time > POWERUP_DURATION: + player_has_triple_shot = False + + for bullet in player_bullets: bullet.update() + for bullet in enemy_bullets: bullet.x -= 10 + for bullet in boss_bullets: bullet.update() + for enemy in enemies: + enemy.x -= ENEMY_SPEED_L3 + if random.randint(0, 100) == 1: + enemy_bullet = pygame.Rect(enemy.left, enemy.centery - 2, 10, 5) + enemy_bullets.append(enemy_bullet) + for asteroid in asteroids: asteroid['rect'].x -= asteroid['speed'] + if powerup_rect: powerup_rect.x -= 3 + if heal_rect: heal_rect.x -= 3 + + if not player_dead: + for bullet in player_bullets[:]: + bullet_removed = False + for asteroid_dict in asteroids[:]: + if bullet.rect.colliderect(asteroid_dict['rect']): + try: + asteroids.remove(asteroid_dict) + player_bullets.remove(bullet) + if explosion_sound: explosion_sound.play() + bullet_removed = True + except ValueError: + pass + break + if bullet_removed: continue + + for enemy in enemies[:]: + if bullet.rect.colliderect(enemy): + try: + enemies.remove(enemy) + player_bullets.remove(bullet) + score += 20 + kill_count += 1 + if explosion_sound: explosion_sound.play() + except ValueError: + pass + break + + for asteroid_dict in asteroids[:]: + if player_rect.colliderect(asteroid_dict['rect']): + asteroids.remove(asteroid_dict) + if not cheat_mode: player_health -= 35 + if explosion_sound: explosion_sound.play() + + for enemy in enemies[:]: + if player_rect.colliderect(enemy): + enemies.remove(enemy) + if not cheat_mode: player_health -= 25 + if explosion_sound: explosion_sound.play() + + for bullet in enemy_bullets[:] + [b.rect for b in boss_bullets]: + if player_rect.colliderect(bullet): + if isinstance(bullet, pygame.Rect) and bullet in enemy_bullets: + enemy_bullets.remove(bullet) + else: + for b in boss_bullets[:]: + if b.rect == bullet: + boss_bullets.remove(b) + break + if not cheat_mode: player_health -= 10 + + if powerup_rect and player_rect.colliderect(powerup_rect): + player_has_triple_shot = True + powerup_active_start_time = pygame.time.get_ticks() + powerup_rect = None + + if heal_rect and player_rect.colliderect(heal_rect): + player_health = min(max_health, player_health + 25) + heal_rect = None + + if kill_count >= kills_for_boss and not boss_fight_active: + boss_fight_active = True + boss_is_entering = True + enemies.clear() + asteroids.clear() + pygame.time.set_timer(ENEMY_SPAWN_EVENT_L3, 0) + pygame.time.set_timer(ASTEROID_SPAWN_EVENT, 0) + boss_rect = boss_image.get_rect(midleft=(SCREEN_WIDTH, SCREEN_HEIGHT / 2)) if boss_image else pygame.Rect(SCREEN_WIDTH, SCREEN_HEIGHT/2-75, 200, 150) + + if boss_fight_active and boss_rect and not boss_defeated: + if boss_is_entering: + entry_target_x = SCREEN_WIDTH - boss_rect.width - 20 + if boss_rect.x > entry_target_x: + boss_rect.x -= 5 + else: + boss_is_entering = False + else: + boss_rect.y += boss_speed * boss_direction + if boss_rect.top <= 0 or boss_rect.bottom >= SCREEN_HEIGHT: + boss_direction *= -1 + if random.randint(0, 30) == 1: + boss_bullets.append(Bullet(boss_rect.left, boss_rect.centery, -15, -3)) + boss_bullets.append(Bullet(boss_rect.left, boss_rect.centery, -15, 0)) + boss_bullets.append(Bullet(boss_rect.left, boss_rect.centery, -15, 3)) + + for bullet in player_bullets[:]: + if bullet.rect.colliderect(boss_rect): + player_bullets.remove(bullet) + boss_health -= 5 + if boss_health <= 0: + boss_defeated = True + if explosion_sound: explosion_sound.play() + pygame.mixer.music.fadeout(2000) + boss_rect = None + break + + if player_health <= 0 and not player_dead: + player_dead = True + if death_sound: death_sound.play() + death_timer_start = pygame.time.get_ticks() + pygame.mixer.music.stop() + + if player_dead: + if pygame.time.get_ticks() - death_timer_start > 2000: + fade_surface = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT)) + fade_surface.fill(BLACK) + for alpha in range(0, 255, 5): + fade_surface.set_alpha(alpha) + screen.blit(fade_surface, (0,0)) + pygame.display.flip() + pygame.time.delay(30) + + died_text = title_font.render("YOU DIED", True, RED) + died_rect = died_text.get_rect(center=(SCREEN_WIDTH/2, SCREEN_HEIGHT/2)) + screen.blit(died_text, died_rect) + pygame.display.flip() + pygame.time.wait(3000) + return + + if boss_defeated: + player_rect.x += PLAYER_SPEED + if player_rect.left > SCREEN_WIDTH: + fade_surface = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT)) + fade_surface.fill(BLACK) + for alpha in range(0, 255, 4): + fade_surface.set_alpha(alpha) + screen.blit(fade_surface, (0,0)) + pygame.display.flip() + pygame.time.delay(30) + + win_text = title_font.render("YOU WIN!", True, WHITE) + win_rect = win_text.get_rect(center=(SCREEN_WIDTH/2, SCREEN_HEIGHT/2)) + screen.blit(win_text, win_rect) + pygame.display.flip() + pygame.time.wait(3000) + credits_screen() + running = False + + screen.fill(BLACK) + for star in stars: + star[0] -= star[2] + if star[0] < 0: star[0] = SCREEN_WIDTH; star[1] = random.randrange(0, SCREEN_HEIGHT) + pygame.draw.rect(screen, WHITE, (star[0], star[1], star[2], star[2])) + + for bullet in player_bullets: pygame.draw.rect(screen, YELLOW, bullet.rect) + for bullet in enemy_bullets: pygame.draw.rect(screen, RED, bullet) + for bullet in boss_bullets: pygame.draw.rect(screen, RED, bullet.rect) + + for asteroid_dict in asteroids: + if asteroid_image: + scaled_asteroid = pygame.transform.scale(asteroid_image, (asteroid_dict['rect'].width, asteroid_dict['rect'].height)) + screen.blit(scaled_asteroid, asteroid_dict['rect']) + else: + pygame.draw.rect(screen, WHITE, asteroid_dict['rect']) + + for enemy in enemies: + if enemy_image: screen.blit(enemy_image, enemy) + else: pygame.draw.rect(screen, RED, enemy) + + if powerup_rect: + if powerup_image: screen.blit(powerup_image, powerup_rect) + else: pygame.draw.rect(screen, CYAN, powerup_rect) + + if heal_rect: + if heal_image: screen.blit(heal_image, heal_rect) + else: pygame.draw.rect(screen, GREEN, heal_rect) + + if boss_rect: + if boss_image: screen.blit(boss_image, boss_rect) + else: pygame.draw.rect(screen, CYAN, boss_rect) + + if not player_dead: + if boss_defeated: + thruster_length = 25 + thruster_rect = pygame.Rect(player_rect.left - thruster_length, player_rect.centery - 5, thruster_length, 10) + pygame.draw.rect(screen, ORANGE, thruster_rect) + if player_image: screen.blit(player_image, player_rect) + else: pygame.draw.rect(screen, PLAYER_COLOR, player_rect) + + health_bar_width = max(0, (player_health / max_health) * 200) if not cheat_mode else 200 + pygame.draw.rect(screen, RED, (10, 10, 200, 20)) + pygame.draw.rect(screen, GREEN, (10, 10, health_bar_width, 20)) + score_text = score_font.render(f"Score: {score}", True, WHITE) + screen.blit(score_text, score_text.get_rect(center=(SCREEN_WIDTH / 2, 20))) + level_text = score_font.render("Level 3", True, WHITE) + screen.blit(level_text, level_text.get_rect(topright=(SCREEN_WIDTH - 10, 10))) + + if player_has_triple_shot: + powerup_icon = pygame.transform.scale(powerup_image, (20, 20)) if powerup_image else None + if powerup_icon: screen.blit(powerup_icon, (10, 35)) + elapsed_time = pygame.time.get_ticks() - powerup_active_start_time + remaining_ratio = 1 - (elapsed_time / POWERUP_DURATION) + timer_bar_width = max(0, remaining_ratio * 175) + pygame.draw.rect(screen, RED, (35, 35, 175, 20)) + pygame.draw.rect(screen, YELLOW, (35, 35, timer_bar_width, 20)) + + if boss_fight_active and not boss_defeated and boss_rect: + boss_health_width = max(0, (boss_health / boss_max_health) * 200) + pygame.draw.rect(screen, RED, (SCREEN_WIDTH - 210, 10, 200, 20)) + pygame.draw.rect(screen, GREEN, (SCREEN_WIDTH - 210, 10, boss_health_width, 20)) + + pygame.display.flip() + clock.tick(60) + +def credits_screen(): + pygame.mixer.music.stop() + try: + pygame.mixer.music.load('credits.wav') + pygame.mixer.music.play(-1) + pygame.mixer.music.set_volume(0.5) + except pygame.error: + print("Warning: 'credits.wav' not found.") + + credit_lines = [ "Credits", "", "Coding: Google Gemini", "Graphics: Google Gemini", "Music: Suno.com", "", "Pygame", "", "Other then me (Michael Howard)", "putting it all together", "A.I. created this game", "", "Thanks for playing" ] + credit_surfaces = [] + line_height = 60 # Increased spacing + start_y = SCREEN_HEIGHT + 50 + for i, line in enumerate(credit_lines): + font = title_font if i == 0 else prompt_font + text_surface = font.render(line, True, WHITE) + text_rect = text_surface.get_rect(center=(SCREEN_WIDTH / 2, start_y + i * line_height)) + credit_surfaces.append({'surf': text_surface, 'rect': text_rect}) + + credit_stars = [[random.uniform(-SCREEN_WIDTH / 2, SCREEN_WIDTH / 2), random.uniform(-SCREEN_HEIGHT / 2, SCREEN_HEIGHT / 2), random.uniform(1, SCREEN_WIDTH)] for _ in range(400)] + scroll_speed = 1.0 # Slower scroll + credits_finished_scrolling = False + prompt_alpha = 0 + + running = True + while running: + for event in pygame.event.get(): + if event.type == pygame.QUIT: + pygame.quit() + sys.exit() + if event.type == pygame.KEYDOWN and credits_finished_scrolling: + return # Go back to main menu loop + + screen.fill(BLACK) + for star in credit_stars: + star[2] -= 2 + if star[2] < 1: + star[2] = SCREEN_WIDTH + star[0], star[1] = random.uniform(-SCREEN_WIDTH / 2, SCREEN_WIDTH / 2), random.uniform(-SCREEN_HEIGHT / 2, SCREEN_HEIGHT / 2) + k = 128.0 / star[2] + sx, sy = int(star[0] * k + SCREEN_WIDTH / 2), int(star[1] * k + SCREEN_HEIGHT / 2) + if 0 < sx < SCREEN_WIDTH and 0 < sy < SCREEN_HEIGHT: + size = (1 - star[2] / SCREEN_WIDTH) * 4 + pygame.draw.rect(screen, WHITE, (sx, sy, size, size)) + + last_rect_bottom = 0 + if not credits_finished_scrolling: + for item in credit_surfaces: + item['rect'].y -= scroll_speed + screen.blit(item['surf'], item['rect']) + last_rect_bottom = item['rect'].bottom + + if last_rect_bottom < -50: + credits_finished_scrolling = True + else: + if prompt_alpha < 255: + prompt_alpha = min(prompt_alpha + 3, 255) + prompt_surface = prompt_font.render("Press any key to continue", True, WHITE) + prompt_surface.set_alpha(prompt_alpha) + prompt_rect = prompt_surface.get_rect(center=(SCREEN_WIDTH / 2, SCREEN_HEIGHT - 50)) + screen.blit(prompt_surface, prompt_rect) + + pygame.display.flip() + clock.tick(60) + +def main_menu(): + try: + pygame.mixer.music.load('CosmicPixels.wav') + pygame.mixer.music.play(-1) + except pygame.error: + print("Warning: Music file 'CosmicPixels.wav' not found.") + + game_title = "COSMIC PIXELS" + full_title_surface = title_font.render(game_title, True, CYAN) + total_width = full_title_surface.get_width() + initial_x = (SCREEN_WIDTH - total_width) / 2 + + title_letters = [] + current_x = initial_x + for char in game_title: + char_surface = title_font.render(char, True, CYAN) + end_pos = (current_x, SCREEN_HEIGHT / 4) + start_pos = (current_x, SCREEN_HEIGHT) + letter = Letter(char, title_font, CYAN, start_pos, end_pos, anim_duration=0.7) + title_letters.append(letter) + current_x += char_surface.get_width() + + next_letter_index, stagger_delay_ms = 0, 80 + last_letter_time = pygame.time.get_ticks() + title_animation_complete = False + prompt_alpha, prompt_fade_speed = 0, 3 + + running = True + while running: + for event in pygame.event.get(): + if event.type == pygame.QUIT: + pygame.quit() + sys.exit() + if event.type == pygame.KEYDOWN and title_animation_complete: + if event.key == pygame.K_0: + level_3_loop(100, 0, cheat_mode=True) + else: + game_loop() + # After a game, the loops will return here, and we just let the main menu loop continue + + screen.fill(BLACK) + for star in stars: + star[0] -= star[2] + if star[0] < 0: + star[0] = SCREEN_WIDTH; star[1] = random.randrange(0, SCREEN_HEIGHT) + pygame.draw.rect(screen, WHITE, (star[0], star[1], star[2], star[2])) + + current_time = pygame.time.get_ticks() + if not title_animation_complete and next_letter_index < len(title_letters): + if current_time - last_letter_time > stagger_delay_ms: + title_letters[next_letter_index].start_animation() + next_letter_index += 1 + last_letter_time = current_time + + all_letters_finished = True + for letter in title_letters: + letter.update(); letter.draw(screen) + if not letter.is_finished: all_letters_finished = False + + if all_letters_finished: title_animation_complete = True + + if title_animation_complete: + if prompt_alpha < 255: prompt_alpha = min(prompt_alpha + prompt_fade_speed, 255) + prompt_surface = prompt_font.render("PRESS ANY KEY TO START", True, YELLOW) + prompt_surface.set_alpha(prompt_alpha) + prompt_rect = prompt_surface.get_rect(center=(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2)) + screen.blit(prompt_surface, prompt_rect) + + pygame.display.flip() + clock.tick(60) + +if __name__ == "__main__": + while True: + main_menu() + diff --git a/mine.jpg b/mine.jpg new file mode 100644 index 0000000..9296204 Binary files /dev/null and b/mine.jpg differ diff --git a/pixel_font.ttf b/pixel_font.ttf new file mode 100644 index 0000000..7c56bc2 Binary files /dev/null and b/pixel_font.ttf differ diff --git a/player_death.wav b/player_death.wav new file mode 100644 index 0000000..44870cd Binary files /dev/null and b/player_death.wav differ diff --git a/powerup_heal.png b/powerup_heal.png new file mode 100644 index 0000000..5a26abc Binary files /dev/null and b/powerup_heal.png differ diff --git a/powerup_triple_shot.png b/powerup_triple_shot.png new file mode 100644 index 0000000..347dbdf Binary files /dev/null and b/powerup_triple_shot.png differ diff --git a/space_mine.png b/space_mine.png new file mode 100644 index 0000000..7a8b1ce Binary files /dev/null and b/space_mine.png differ