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()