"""
二维移动射击游戏
开发者: 卢思成
学校: 东台市第一小学
班级: 六（10）班
学号: 19号
版本: 1.0
"""

import pygame
import random
import math
import sys
from enum import Enum

# 初始化pygame
pygame.init()

# 游戏常量
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
FPS = 60
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 50, 50)
GREEN = (50, 255, 50)
BLUE = (50, 100, 255)
YELLOW = (255, 255, 50)
PURPLE = (180, 70, 255)
CYAN = (0, 200, 200)
ORANGE = (255, 150, 50)
BACKGROUND_COLOR = (10, 10, 30)
GRID_COLOR = (20, 20, 40)


class GameState(Enum):
    """游戏状态"""
    MENU = 1
    PLAYING = 2
    PAUSED = 3
    GAME_OVER = 4
    LEVEL_COMPLETE = 5


class Particle:
    """粒子效果"""

    def __init__(self, x, y, color, velocity_x=0, velocity_y=0, size=3, lifetime=30):
        self.x = x
        self.y = y
        self.color = color
        self.velocity_x = velocity_x
        self.velocity_y = velocity_y
        self.size = size
        self.lifetime = lifetime
        self.max_lifetime = lifetime

    def update(self):
        self.x += self.velocity_x
        self.y += self.velocity_y
        self.velocity_x *= 0.98
        self.velocity_y *= 0.98
        self.lifetime -= 1
        self.size = max(0, self.size * 0.95)

    def draw(self, screen):
        alpha = int(255 * (self.lifetime / self.max_lifetime))
        pygame.draw.circle(screen, self.color, (int(
            self.x), int(self.y)), int(self.size))

    def is_alive(self):
        return self.lifetime > 0


class Player:
    """玩家类"""

    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.width = 30
        self.height = 40
        self.speed = 5
        self.health = 100
        self.max_health = 100
        self.score = 0
        self.kills = 0
        self.level = 1
        self.experience = 0
        self.experience_to_next_level = 100
        self.weapon_level = 1
        self.fire_rate = 0.3
        self.last_shot_time = 0
        self.invincible = False
        self.invincible_timer = 0
        self.color = BLUE

    def move(self, dx, dy, screen_width, screen_height):
        new_x = self.x + dx * self.speed
        new_y = self.y + dy * self.speed

        if 0 <= new_x <= screen_width - self.width:
            self.x = new_x
        if 0 <= new_y <= screen_height - self.height:
            self.y = new_y

    def take_damage(self, amount):
        if not self.invincible:
            self.health = max(0, self.health - amount)
            self.invincible = True
            self.invincible_timer = 60
            return True
        return False

    def heal(self, amount):
        self.health = min(self.max_health, self.health + amount)

    def add_experience(self, amount):
        self.experience += amount
        if self.experience >= self.experience_to_next_level:
            self.level_up()

    def level_up(self):
        self.level += 1
        self.experience -= self.experience_to_next_level
        self.experience_to_next_level = int(
            self.experience_to_next_level * 1.5)
        self.max_health += 20
        self.health = self.max_health
        self.weapon_level = min(5, self.weapon_level + 1)
        self.fire_rate = max(0.1, self.fire_rate - 0.05)

    def update(self):
        if self.invincible:
            self.invincible_timer -= 1
            if self.invincible_timer <= 0:
                self.invincible = False

    def draw(self, screen):
        points = [
            (self.x + self.width // 2, self.y),
            (self.x + self.width, self.y + self.height),
            (self.x + self.width // 2, self.y + self.height * 0.7),
            (self.x, self.y + self.height)
        ]

        if self.invincible and pygame.time.get_ticks() % 200 < 100:
            color = WHITE
        else:
            color = self.color

        pygame.draw.polygon(screen, color, points)
        pygame.draw.polygon(screen, WHITE, points, 2)

    def get_rect(self):
        return pygame.Rect(self.x, self.y, self.width, self.height)

    def can_shoot(self, current_time):
        return (current_time - self.last_shot_time) >= (self.fire_rate * 1000)

    def shoot(self, bullets, current_time):
        if self.can_shoot(current_time):
            self.last_shot_time = current_time

            bullet_x = self.x + self.width // 2
            bullet_y = self.y

            if self.weapon_level == 1:
                bullets.append(Bullet(bullet_x, bullet_y, 0, -10, YELLOW))
            elif self.weapon_level == 2:
                bullets.append(Bullet(bullet_x - 5, bullet_y, 0, -10, YELLOW))
                bullets.append(Bullet(bullet_x + 5, bullet_y, 0, -10, YELLOW))
            elif self.weapon_level == 3:
                bullets.append(Bullet(bullet_x, bullet_y, 0, -10, YELLOW))
                bullets.append(Bullet(bullet_x - 8, bullet_y, -1, -9, YELLOW))
                bullets.append(Bullet(bullet_x + 8, bullet_y, 1, -9, YELLOW))
            elif self.weapon_level == 4:
                bullets.append(Bullet(bullet_x, bullet_y, 0, -10, YELLOW))
                bullets.append(Bullet(bullet_x - 8, bullet_y, -1, -9, YELLOW))
                bullets.append(Bullet(bullet_x + 8, bullet_y, 1, -9, YELLOW))
                bullets.append(Bullet(bullet_x, bullet_y, 0, -12, YELLOW))
            else:
                bullets.append(Bullet(bullet_x, bullet_y, 0, -10, YELLOW))
                bullets.append(Bullet(bullet_x - 8, bullet_y, -1, -9, YELLOW))
                bullets.append(Bullet(bullet_x + 8, bullet_y, 1, -9, YELLOW))
                bullets.append(Bullet(bullet_x - 15, bullet_y, -2, -8, YELLOW))
                bullets.append(Bullet(bullet_x + 15, bullet_y, 2, -8, YELLOW))

            return True
        return False


class Bullet:
    """子弹类"""

    def __init__(self, x, y, dx, dy, color=YELLOW, damage=10, size=5):
        self.x = x
        self.y = y
        self.dx = dx
        self.dy = dy
        self.color = color
        self.damage = damage
        self.size = size

    def update(self):
        self.x += self.dx
        self.y += self.dy

    def draw(self, screen):
        pygame.draw.circle(screen, self.color,
                           (int(self.x), int(self.y)), self.size)
        pygame.draw.circle(
            screen, WHITE, (int(self.x), int(self.y)), self.size, 1)

    def is_off_screen(self, screen_width, screen_height):
        return (self.x < 0 or self.x > screen_width or
                self.y < 0 or self.y > screen_height)

    def get_rect(self):
        return pygame.Rect(self.x - self.size, self.y - self.size,
                           self.size * 2, self.size * 2)


class Enemy:
    """敌人基类"""

    def __init__(self, x, y, enemy_type="normal"):
        self.x = x
        self.y = y
        self.type = enemy_type
        self.width = 30
        self.height = 30
        self.health = 20
        self.max_health = 20
        self.speed = 1.5
        self.color = RED
        self.points = 10
        self.experience = 5
        self.last_shot_time = 0
        self.fire_rate = 2.0

        if enemy_type == "fast":
            self.color = GREEN
            self.speed = 3.0
            self.health = 10
            self.max_health = 10
            self.points = 15
            self.experience = 8
        elif enemy_type == "tank":
            self.color = ORANGE
            self.speed = 0.8
            self.health = 50
            self.max_health = 50
            self.width = 40
            self.height = 40
            self.points = 30
            self.experience = 20
        elif enemy_type == "shooter":
            self.color = PURPLE
            self.speed = 1.2
            self.health = 15
            self.max_health = 15
            self.fire_rate = 1.0
            self.points = 20
            self.experience = 12

    def update(self, player_x, player_y):
        dx = player_x - self.x
        dy = player_y - self.y
        dist = max(1, math.sqrt(dx*dx + dy*dy))

        self.x += (dx / dist) * self.speed
        self.y += (dy / dist) * self.speed

    def take_damage(self, amount):
        self.health = max(0, self.health - amount)
        return self.health <= 0

    def shoot(self, bullets, current_time, player_x, player_y):
        if (current_time - self.last_shot_time) >= (self.fire_rate * 1000):
            self.last_shot_time = current_time

            if self.type == "shooter":
                dx = player_x - self.x
                dy = player_y - self.y
                dist = max(1, math.sqrt(dx*dx + dy*dy))

                bullet_dx = (dx / dist) * 5
                bullet_dy = (dy / dist) * 5

                bullets.append(
                    EnemyBullet(self.x + self.width//2, self.y + self.height//2,
                                bullet_dx, bullet_dy, PURPLE, 5)
                )
                return True
        return False

    def draw(self, screen):
        if self.type == "normal":
            pygame.draw.rect(screen, self.color,
                             (self.x, self.y, self.width, self.height))
            pygame.draw.rect(screen, WHITE,
                             (self.x, self.y, self.width, self.height), 2)

        elif self.type == "fast":
            points = [
                (self.x + self.width//2, self.y),
                (self.x + self.width, self.y + self.height),
                (self.x, self.y + self.height)
            ]
            pygame.draw.polygon(screen, self.color, points)
            pygame.draw.polygon(screen, WHITE, points, 2)

        elif self.type == "tank":
            pygame.draw.circle(screen, self.color,
                               (int(self.x + self.width//2),
                                int(self.y + self.height//2)),
                               self.width//2)
            pygame.draw.circle(screen, WHITE,
                               (int(self.x + self.width//2),
                                int(self.y + self.height//2)),
                               self.width//2, 2)

        elif self.type == "shooter":
            points = [
                (self.x + self.width//2, self.y),
                (self.x + self.width, self.y + self.height//2),
                (self.x + self.width//2, self.y + self.height),
                (self.x, self.y + self.height//2)
            ]
            pygame.draw.polygon(screen, self.color, points)
            pygame.draw.polygon(screen, WHITE, points, 2)

        if self.health < self.max_health:
            health_width = 30
            health_height = 4
            health_x = self.x + (self.width - health_width) // 2
            health_y = self.y - 10

            pygame.draw.rect(screen, (100, 0, 0),
                             (health_x, health_y, health_width, health_height))
            health_percent = self.health / self.max_health
            pygame.draw.rect(screen, GREEN,
                             (health_x, health_y, int(health_width * health_percent), health_height))

    def get_rect(self):
        return pygame.Rect(self.x, self.y, self.width, self.height)


class EnemyBullet(Bullet):
    """敌人子弹"""

    def __init__(self, x, y, dx, dy, color=PURPLE, damage=5):
        super().__init__(x, y, dx, dy, color, damage, 4)


class PowerUp:
    """道具类"""

    def __init__(self, x, y, power_type="health"):
        self.x = x
        self.y = y
        self.type = power_type
        self.width = 20
        self.height = 20
        self.speed = 2

        if power_type == "health":
            self.color = RED
        elif power_type == "weapon":
            self.color = YELLOW
        elif power_type == "speed":
            self.color = GREEN
        elif power_type == "shield":
            self.color = BLUE

    def update(self):
        self.y += self.speed

    def draw(self, screen):
        if self.type == "health":
            pygame.draw.rect(screen, self.color,
                             (self.x + self.width//2 - 2, self.y, 4, self.height))
            pygame.draw.rect(screen, self.color,
                             (self.x, self.y + self.height//2 - 2, self.width, 4))
        elif self.type == "weapon":
            points = []
            for i in range(5):
                angle = math.pi/2 + i * 2*math.pi/5
                outer_x = self.x + self.width//2 + \
                    math.cos(angle) * (self.width//2)
                outer_y = self.y + self.height//2 + \
                    math.sin(angle) * (self.height//2)
                points.append((outer_x, outer_y))

                angle += math.pi/5
                inner_x = self.x + self.width//2 + \
                    math.cos(angle) * (self.width//4)
                inner_y = self.y + self.height//2 + \
                    math.sin(angle) * (self.height//4)
                points.append((inner_x, inner_y))

            pygame.draw.polygon(screen, self.color, points)
        else:
            points = [
                (self.x + self.width//2, self.y),
                (self.x + self.width, self.y + self.height//2),
                (self.x + self.width//2, self.y + self.height),
                (self.x, self.y + self.height//2)
            ]
            pygame.draw.polygon(screen, self.color, points)

    def get_rect(self):
        return pygame.Rect(self.x, self.y, self.width, self.height)

    def apply(self, player):
        if self.type == "health":
            player.heal(20)
            return "生命值 +20!"
        elif self.type == "weapon":
            player.weapon_level = min(5, player.weapon_level + 1)
            player.fire_rate = max(0.1, player.fire_rate - 0.05)
            return "武器升级!"
        elif self.type == "speed":
            player.speed += 1
            return "速度提升!"
        elif self.type == "shield":
            player.invincible = True
            player.invincible_timer = 180
            return "无敌护盾!"
        return ""


class ShootingGame:
    """游戏主类"""

    def __init__(self):
        self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
        pygame.display.set_caption("星际射手 - 卢思成制作")

        self.state = GameState.MENU
        self.clock = pygame.time.Clock()
        self.running = True

        self.player = None
        self.bullets = []
        self.enemy_bullets = []
        self.enemies = []
        self.power_ups = []

        self.score = 0
        self.wave = 1
        self.enemies_per_wave = 5
        self.enemies_spawned = 0
        self.enemies_defeated = 0
        self.wave_complete = False
        self.spawn_timer = 0
        self.spawn_delay = 60
        self.message = ""
        self.message_timer = 0
        self.starfield = []

        self.title_font = pygame.font.Font(None, 72)
        self.large_font = pygame.font.Font(None, 48)
        self.medium_font = pygame.font.Font(None, 36)
        self.small_font = pygame.font.Font(None, 24)

        self.init_starfield()

        self.developer_info = {
            "name": "卢思成",
            "school": "东台市第一小学",
            "class": "六（10）班",
            "number": "19号"
        }

        self.instructions = [
            "操作说明:",
            "WASD/方向键: 移动",
            "空格键: 射击",
            "P键: 暂停游戏",
            "ESC键: 返回菜单/退出",
            "",
            "游戏目标:",
            "1. 消灭所有敌人通过关卡",
            "2. 收集道具提升能力",
            "3. 获得高分并升级",
            "",
            "道具说明:",
            "红色十字: 恢复生命值",
            "黄色星星: 升级武器",
            "绿色菱形: 提升速度",
            "蓝色菱形: 获得无敌护盾"
        ]

    def init_starfield(self):
        self.starfield = []
        for _ in range(100):
            x = random.randint(0, SCREEN_WIDTH)
            y = random.randint(0, SCREEN_HEIGHT)
            speed = random.uniform(0.5, 2.0)
            size = random.randint(1, 3)
            brightness = random.randint(150, 255)
            self.starfield.append({
                'x': x, 'y': y, 'speed': speed, 'size': size, 'brightness': brightness
            })

    def draw_starfield(self):
        self.screen.fill(BACKGROUND_COLOR)

        grid_size = 50
        for x in range(0, SCREEN_WIDTH, grid_size):
            pygame.draw.line(self.screen, GRID_COLOR,
                             (x, 0), (x, SCREEN_HEIGHT), 1)
        for y in range(0, SCREEN_HEIGHT, grid_size):
            pygame.draw.line(self.screen, GRID_COLOR,
                             (0, y), (SCREEN_WIDTH, y), 1)

        for star in self.starfield:
            color = (star['brightness'],
                     star['brightness'], star['brightness'])
            pygame.draw.circle(self.screen, color, (int(
                star['x']), int(star['y'])), star['size'])

            star['y'] += star['speed']
            if star['y'] > SCREEN_HEIGHT:
                star['y'] = 0
                star['x'] = random.randint(0, SCREEN_WIDTH)

    def start_game(self):
        self.player = Player(SCREEN_WIDTH // 2 - 15, SCREEN_HEIGHT - 100)
        self.bullets = []
        self.enemy_bullets = []
        self.enemies = []
        self.power_ups = []

        self.score = 0
        self.wave = 1
        self.enemies_per_wave = 5
        self.enemies_spawned = 0
        self.enemies_defeated = 0
        self.wave_complete = False
        self.spawn_timer = 0

        self.state = GameState.PLAYING
        self.show_message(f"第 {self.wave} 关开始!", GREEN)

    def spawn_enemy(self):
        if self.enemies_spawned >= self.wave * self.enemies_per_wave:
            return

        enemy_types = ["normal", "fast", "tank", "shooter"]
        weights = [0.4, 0.3, 0.2, 0.1]

        if self.wave > 3:
            weights = [0.2, 0.3, 0.3, 0.2]

        enemy_type = random.choices(enemy_types, weights=weights, k=1)[0]

        x = random.randint(0, SCREEN_WIDTH - 30)
        y = random.randint(-100, -30)

        self.enemies.append(Enemy(x, y, enemy_type))
        self.enemies_spawned += 1

    def spawn_power_up(self, x, y):
        power_types = ["health", "weapon", "speed", "shield"]
        weights = [0.4, 0.3, 0.2, 0.1]

        power_type = random.choices(power_types, weights=weights, k=1)[0]
        self.power_ups.append(PowerUp(x, y, power_type))

    def create_explosion(self, x, y, color=ORANGE, count=20):
        for _ in range(count):
            angle = random.uniform(0, math.pi * 2)
            speed = random.uniform(1, 5)
            velocity_x = math.cos(angle) * speed
            velocity_y = math.sin(angle) * speed
            size = random.randint(2, 4)
            lifetime = random.randint(20, 40)

            self.screen.blit(self.screen, (0, 0))

    def show_message(self, text, color=WHITE, duration=60):
        self.message = text
        self.message_color = color
        self.message_timer = duration

    def draw_ui(self):
        score_text = self.medium_font.render(
            f"分数: {self.score:,}", True, YELLOW)
        self.screen.blit(score_text, (10, 10))

        wave_text = self.medium_font.render(f"关卡: {self.wave}", True, CYAN)
        self.screen.blit(wave_text, (10, 50))

        health_width = 200
        health_height = 20
        health_x = SCREEN_WIDTH - health_width - 10
        health_y = 10

        pygame.draw.rect(self.screen, (100, 0, 0),
                         (health_x, health_y, health_width, health_height))
        health_percent = self.player.health / self.player.max_health
        health_fill_width = int(health_width * health_percent)
        pygame.draw.rect(self.screen, GREEN,
                         (health_x, health_y, health_fill_width, health_height))
        pygame.draw.rect(self.screen, WHITE,
                         (health_x, health_y, health_width, health_height), 2)

        health_text = f"{self.player.health:.0f}/{self.player.max_health:.0f}"
        health_render = self.small_font.render(health_text, True, WHITE)
        self.screen.blit(health_render, (health_x + health_width//2 - health_render.get_width()//2,
                                         health_y + health_height//2 - health_render.get_height()//2))

        if self.message and self.message_timer > 0:
            message_render = self.medium_font.render(
                self.message, True, self.message_color)
            self.screen.blit(message_render,
                             (SCREEN_WIDTH//2 - message_render.get_width()//2, 100))
            self.message_timer -= 1

        if self.state == GameState.PLAYING:
            controls = ["移动: WASD/方向键  射击: 空格键  暂停: P"]

            for i, text in enumerate(controls):
                control_render = self.small_font.render(
                    text, True, (200, 200, 200))
                self.screen.blit(control_render,
                                 (SCREEN_WIDTH//2 - control_render.get_width()//2,
                                  SCREEN_HEIGHT - 40))

    def draw_menu(self):
        title_text = self.title_font.render("星际射手", True, CYAN)
        self.screen.blit(title_text, (SCREEN_WIDTH//2 -
                         title_text.get_width()//2, 100))

        subtitle = self.medium_font.render("二维移动射击游戏", True, YELLOW)
        self.screen.blit(subtitle, (SCREEN_WIDTH//2 -
                         subtitle.get_width()//2, 180))

        button_width, button_height = 200, 50
        button_x = SCREEN_WIDTH//2 - button_width//2

        start_button = pygame.Rect(button_x, 250, button_width, button_height)
        pygame.draw.rect(self.screen, GREEN, start_button, border_radius=10)
        pygame.draw.rect(self.screen, WHITE, start_button, 3, border_radius=10)

        start_text = self.medium_font.render("开始游戏", True, WHITE)
        self.screen.blit(start_text, (button_x + button_width//2 - start_text.get_width()//2,
                                      265))

        if self.player and self.player.health > 0:
            continue_button = pygame.Rect(
                button_x, 320, button_width, button_height)
            pygame.draw.rect(self.screen, BLUE,
                             continue_button, border_radius=10)
            pygame.draw.rect(self.screen, WHITE,
                             continue_button, 3, border_radius=10)

            continue_text = self.medium_font.render("继续游戏", True, WHITE)
            self.screen.blit(continue_text, (button_x + button_width//2 - continue_text.get_width()//2,
                                             335))

        quit_button = pygame.Rect(button_x, 390 if self.player and self.player.health > 0 else 320,
                                  button_width, button_height)
        pygame.draw.rect(self.screen, RED, quit_button, border_radius=10)
        pygame.draw.rect(self.screen, WHITE, quit_button, 3, border_radius=10)

        quit_text = self.medium_font.render("退出游戏", True, WHITE)
        self.screen.blit(quit_text, (quit_button.x + button_width//2 - quit_text.get_width()//2,
                                     quit_button.y + 15))

        y_offset = 450
        for i, line in enumerate(self.instructions[:8]):
            if line.startswith("操作说明") or line.startswith("游戏目标"):
                text = self.small_font.render(line, True, YELLOW)
            else:
                text = self.small_font.render(line, True, (200, 200, 200))

            self.screen.blit(
                text, (SCREEN_WIDTH//2 - text.get_width()//2, y_offset + i * 20))

        dev_text = f"开发者: {self.developer_info['name']}  {self.developer_info['school']} {self.developer_info['class']} {self.developer_info['number']}"
        dev_render = self.small_font.render(dev_text, True, (150, 150, 150))
        self.screen.blit(dev_render, (SCREEN_WIDTH//2 - dev_render.get_width()//2,
                                      SCREEN_HEIGHT - 30))

        return start_button, continue_button if (self.player and self.player.health > 0) else None, quit_button

    def draw_pause_menu(self):
        overlay = pygame.Surface(
            (SCREEN_WIDTH, SCREEN_HEIGHT), pygame.SRCALPHA)
        overlay.fill((0, 0, 0, 150))
        self.screen.blit(overlay, (0, 0))

        pause_text = self.title_font.render("游戏暂停", True, YELLOW)
        self.screen.blit(pause_text, (SCREEN_WIDTH//2 -
                         pause_text.get_width()//2, 150))

        button_width, button_height = 200, 50
        button_x = SCREEN_WIDTH//2 - button_width//2

        continue_button = pygame.Rect(
            button_x, 250, button_width, button_height)
        pygame.draw.rect(self.screen, GREEN, continue_button, border_radius=10)
        pygame.draw.rect(self.screen, WHITE, continue_button,
                         3, border_radius=10)

        continue_text = self.medium_font.render("继续游戏", True, WHITE)
        self.screen.blit(continue_text, (button_x + button_width//2 - continue_text.get_width()//2,
                                         265))

        menu_button = pygame.Rect(button_x, 320, button_width, button_height)
        pygame.draw.rect(self.screen, BLUE, menu_button, border_radius=10)
        pygame.draw.rect(self.screen, WHITE, menu_button, 3, border_radius=10)

        menu_text = self.medium_font.render("返回菜单", True, WHITE)
        self.screen.blit(menu_text, (button_x + button_width//2 - menu_text.get_width()//2,
                                     335))

        return continue_button, menu_button

    def draw_game_over(self):
        overlay = pygame.Surface(
            (SCREEN_WIDTH, SCREEN_HEIGHT), pygame.SRCALPHA)
        overlay.fill((0, 0, 0, 200))
        self.screen.blit(overlay, (0, 0))

        game_over_text = self.title_font.render("游戏结束", True, RED)
        self.screen.blit(game_over_text, (SCREEN_WIDTH//2 -
                         game_over_text.get_width()//2, 100))

        stats = [
            f"最终分数: {self.score:,}",
            f"通关关卡: {self.wave}",
            f"消灭敌人: {self.player.kills}",
        ]

        y_offset = 200
        for i, stat in enumerate(stats):
            stat_text = self.medium_font.render(stat, True, WHITE)
            self.screen.blit(stat_text, (SCREEN_WIDTH//2 -
                             stat_text.get_width()//2, y_offset + i * 40))

        button_width, button_height = 200, 50
        button_x = SCREEN_WIDTH//2 - button_width//2
        button_y = 350

        restart_button = pygame.Rect(
            button_x, button_y, button_width, button_height)
        pygame.draw.rect(self.screen, GREEN, restart_button, border_radius=10)
        pygame.draw.rect(self.screen, WHITE, restart_button,
                         3, border_radius=10)

        restart_text = self.medium_font.render("重新开始", True, WHITE)
        self.screen.blit(restart_text, (button_x + button_width//2 - restart_text.get_width()//2,
                                        button_y + 15))

        menu_button = pygame.Rect(
            button_x, button_y + 70, button_width, button_height)
        pygame.draw.rect(self.screen, BLUE, menu_button, border_radius=10)
        pygame.draw.rect(self.screen, WHITE, menu_button, 3, border_radius=10)

        menu_text = self.medium_font.render("返回菜单", True, WHITE)
        self.screen.blit(menu_text, (button_x + button_width//2 - menu_text.get_width()//2,
                                     button_y + 85))

        return restart_button, menu_button

    def draw_level_complete(self):
        overlay = pygame.Surface(
            (SCREEN_WIDTH, SCREEN_HEIGHT), pygame.SRCALPHA)
        overlay.fill((0, 0, 0, 200))
        self.screen.blit(overlay, (0, 0))

        complete_text = self.title_font.render(
            f"第 {self.wave} 关完成!", True, GREEN)
        self.screen.blit(complete_text, (SCREEN_WIDTH//2 -
                         complete_text.get_width()//2, 100))

        stats = [
            f"当前分数: {self.score:,}",
            f"消灭敌人: {self.player.kills}",
            f"玩家等级: {self.player.level}",
        ]

        y_offset = 200
        for i, stat in enumerate(stats):
            stat_text = self.medium_font.render(stat, True, WHITE)
            self.screen.blit(stat_text, (SCREEN_WIDTH//2 -
                             stat_text.get_width()//2, y_offset + i * 40))

        button_width, button_height = 200, 50
        button_x = SCREEN_WIDTH//2 - button_width//2
        button_y = 350

        next_button = pygame.Rect(
            button_x, button_y, button_width, button_height)
        pygame.draw.rect(self.screen, GREEN, next_button, border_radius=10)
        pygame.draw.rect(self.screen, WHITE, next_button, 3, border_radius=10)

        next_button_text = self.medium_font.render("下一关", True, WHITE)
        self.screen.blit(next_button_text, (button_x + button_width//2 - next_button_text.get_width()//2,
                                            button_y + 15))

        return next_button

    def update(self):
        if self.state != GameState.PLAYING:
            return

        current_time = pygame.time.get_ticks()

        self.player.update()

        for bullet in self.bullets[:]:
            bullet.update()
            if bullet.is_off_screen(SCREEN_WIDTH, SCREEN_HEIGHT):
                self.bullets.remove(bullet)

        for bullet in self.enemy_bullets[:]:
            bullet.update()
            if bullet.is_off_screen(SCREEN_WIDTH, SCREEN_HEIGHT):
                self.enemy_bullets.remove(bullet)

            if bullet.get_rect().colliderect(self.player.get_rect()):
                if self.player.take_damage(bullet.damage):
                    self.state = GameState.GAME_OVER
                self.enemy_bullets.remove(bullet)

        for enemy in self.enemies[:]:
            enemy.update(self.player.x + self.player.width//2,
                         self.player.y + self.player.height//2)

            if enemy.shoot(self.enemy_bullets, current_time,
                           self.player.x + self.player.width//2,
                           self.player.y + self.player.height//2):
                pass

            if enemy.y > SCREEN_HEIGHT:
                self.enemies.remove(enemy)
                self.enemies_defeated += 1

                if self.enemies_defeated >= self.wave * self.enemies_per_wave:
                    self.wave_complete = True

            if enemy.get_rect().colliderect(self.player.get_rect()):
                if self.player.take_damage(20):
                    self.state = GameState.GAME_OVER

                self.enemies.remove(enemy)
                self.enemies_defeated += 1

        for bullet in self.bullets[:]:
            for enemy in self.enemies[:]:
                if bullet.get_rect().colliderect(enemy.get_rect()):
                    if enemy.take_damage(bullet.damage):
                        self.score += enemy.points
                        self.player.score += enemy.points
                        self.player.kills += 1
                        self.player.add_experience(enemy.experience)
                        self.show_message(f"+{enemy.points} 分数!", GREEN)

                        if random.random() < 0.3:
                            self.spawn_power_up(enemy.x + enemy.width//2,
                                                enemy.y + enemy.height//2)

                        self.enemies.remove(enemy)
                        self.enemies_defeated += 1
                        break

            if bullet in self.bullets:
                self.bullets.remove(bullet)

        for power_up in self.power_ups[:]:
            power_up.update()

            if power_up.y > SCREEN_HEIGHT:
                self.power_ups.remove(power_up)
                continue

            if power_up.get_rect().colliderect(self.player.get_rect()):
                message = power_up.apply(self.player)
                self.show_message(message, power_up.color)
                self.power_ups.remove(power_up)

        if not self.wave_complete and self.enemies_spawned < self.wave * self.enemies_per_wave:
            self.spawn_timer += 1
            if self.spawn_timer >= self.spawn_delay:
                self.spawn_enemy()
                self.spawn_timer = 0

        if self.wave_complete and len(self.enemies) == 0:
            self.state = GameState.LEVEL_COMPLETE

    def draw(self):
        self.draw_starfield()

        if self.state == GameState.PLAYING:
            for power_up in self.power_ups:
                power_up.draw(self.screen)

            for bullet in self.bullets:
                bullet.draw(self.screen)

            for bullet in self.enemy_bullets:
                bullet.draw(self.screen)

            for enemy in self.enemies:
                enemy.draw(self.screen)

            self.player.draw(self.screen)

            self.draw_ui()

        elif self.state == GameState.MENU:
            self.draw_menu()

        elif self.state == GameState.PAUSED:
            for power_up in self.power_ups:
                power_up.draw(self.screen)

            for bullet in self.bullets:
                bullet.draw(self.screen)

            for bullet in self.enemy_bullets:
                bullet.draw(self.screen)

            for enemy in self.enemies:
                enemy.draw(self.screen)

            self.player.draw(self.screen)

            self.draw_ui()
            self.draw_pause_menu()

        elif self.state == GameState.GAME_OVER:
            for power_up in self.power_ups:
                power_up.draw(self.screen)

            for bullet in self.bullets:
                bullet.draw(self.screen)

            for bullet in self.enemy_bullets:
                bullet.draw(self.screen)

            for enemy in self.enemies:
                enemy.draw(self.screen)

            self.player.draw(self.screen)

            self.draw_ui()
            self.draw_game_over()

        elif self.state == GameState.LEVEL_COMPLETE:
            for power_up in self.power_ups:
                power_up.draw(self.screen)

            for bullet in self.bullets:
                bullet.draw(self.screen)

            for bullet in self.enemy_bullets:
                bullet.draw(self.screen)

            for enemy in self.enemies:
                enemy.draw(self.screen)

            self.player.draw(self.screen)

            self.draw_ui()
            self.draw_level_complete()

    def handle_input(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.running = False

            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    if self.state == GameState.PLAYING or self.state == GameState.PAUSED:
                        self.state = GameState.MENU
                    elif self.state == GameState.MENU:
                        self.running = False

                elif event.key == pygame.K_p:
                    if self.state == GameState.PLAYING:
                        self.state = GameState.PAUSED
                    elif self.state == GameState.PAUSED:
                        self.state = GameState.PLAYING

                elif event.key == pygame.K_SPACE:
                    if self.state == GameState.PLAYING:
                        self.player.shoot(
                            self.bullets, pygame.time.get_ticks())

                elif event.key == pygame.K_r:
                    if self.state == GameState.GAME_OVER:
                        self.start_game()

            elif event.type == pygame.MOUSEBUTTONDOWN:
                mouse_pos = pygame.mouse.get_pos()

                if self.state == GameState.MENU:
                    start_button, continue_button, quit_button = self.draw_menu()

                    if start_button.collidepoint(mouse_pos):
                        self.start_game()

                    if continue_button and continue_button.collidepoint(mouse_pos):
                        if self.player and self.player.health > 0:
                            self.state = GameState.PLAYING

                    if quit_button.collidepoint(mouse_pos):
                        self.running = False

                elif self.state == GameState.PAUSED:
                    continue_button, menu_button = self.draw_pause_menu()

                    if continue_button.collidepoint(mouse_pos):
                        self.state = GameState.PLAYING

                    if menu_button.collidepoint(mouse_pos):
                        self.state = GameState.MENU

                elif self.state == GameState.GAME_OVER:
                    restart_button, menu_button = self.draw_game_over()

                    if restart_button.collidepoint(mouse_pos):
                        self.start_game()

                    if menu_button.collidepoint(mouse_pos):
                        self.state = GameState.MENU

                elif self.state == GameState.LEVEL_COMPLETE:
                    next_button = self.draw_level_complete()

                    if next_button.collidepoint(mouse_pos):
                        self.wave += 1
                        self.enemies_spawned = 0
                        self.enemies_defeated = 0
                        self.wave_complete = False
                        self.state = GameState.PLAYING
                        self.show_message(f"第 {self.wave} 关开始!", GREEN)

        if self.state == GameState.PLAYING:
            keys = pygame.key.get_pressed()
            dx, dy = 0, 0

            if keys[pygame.K_LEFT] or keys[pygame.K_a]:
                dx -= 1
            if keys[pygame.K_RIGHT] or keys[pygame.K_d]:
                dx += 1
            if keys[pygame.K_UP] or keys[pygame.K_w]:
                dy -= 1
            if keys[pygame.K_DOWN] or keys[pygame.K_s]:
                dy += 1

            if dx != 0 or dy != 0:
                if dx != 0 and dy != 0:
                    dx *= 0.7071
                    dy *= 0.7071

                self.player.move(dx, dy, SCREEN_WIDTH, SCREEN_HEIGHT)

            if keys[pygame.K_SPACE]:
                self.player.shoot(self.bullets, pygame.time.get_ticks())

    def run(self):
        print("""
        二维移动射击游戏
        开发者: 卢思成
        学校: 东台市第一小学
        班级: 六（10）班
        学号: 19号
        
        操作说明:
        WASD/方向键: 移动
        空格键: 射击
        P键: 暂停游戏
        ESC键: 返回菜单/退出游戏
        
        游戏目标:
        1. 消灭所有敌人通过关卡
        2. 收集道具提升能力
        3. 获得高分并升级
        
        道具说明:
        红色十字: 恢复生命值
        黄色星星: 升级武器
        绿色菱形: 提升速度
        蓝色菱形: 获得无敌护盾
        """)

        while self.running:
            self.handle_input()
            self.update()
            self.draw()
            pygame.display.flip()
            self.clock.tick(FPS)

        pygame.quit()
        sys.exit()


if __name__ == "__main__":
    try:
        game = ShootingGame()
        game.run()
    except Exception as e:
        print(f"游戏启动出错: {e}")
        import traceback
        traceback.print_exc()
        input("按回车键退出...")
