import pygame
import sys
import random
import math
from enum import Enum

# 初始化pygame
pygame.init()
pygame.mixer.init()

# 窗口设置
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("星际飞行躲避")
clock = pygame.time.Clock()

# 颜色定义
SPACE_BLACK = (10, 10, 20)
STAR_WHITE = (255, 255, 255)
STAR_YELLOW = (255, 255, 200)
NEBULA_PURPLE = (128, 0, 128, 30)
NEBULA_BLUE = (0, 100, 200, 30)
PLAYER_COLOR = (0, 200, 255)
PLAYER_TRAIL = (0, 150, 255, 100)
BULLET_COLOR = (255, 255, 0)
ENEMY_RED = (255, 50, 50)
ENEMY_BLUE = (50, 150, 255)
ENEMY_GREEN = (50, 255, 100)
ENEMY_PURPLE = (200, 50, 200)
BOSS_COLOR = (255, 100, 0)
EXPLOSION_COLOR = (255, 200, 0)
POWERUP_COLOR = (0, 255, 255)
SHIELD_COLOR = (0, 200, 255, 100)
TEXT_WHITE = (255, 255, 255)
TEXT_GREEN = (50, 255, 100)
TEXT_RED = (255, 50, 50)
TEXT_GOLD = (255, 215, 0)
UI_BG = (20, 20, 30, 200)
HEALTH_COLOR = (0, 255, 0)
HEALTH_LOW = (255, 50, 50)
HEALTH_MID = (255, 255, 0)

# 游戏常量
PLAYER_SPEED = 5
PLAYER_SIZE = 20
PLAYER_HEALTH = 100
BULLET_SPEED = 8
BULLET_SIZE = 4
ENEMY_SPEED_MIN = 1
ENEMY_SPEED_MAX = 3
STAR_COUNT = 100
PARTICLE_COUNT = 30
WAVE_DURATION = 1000  # 波次持续时间（帧）
BOSS_HEALTH = 500
BOSS_SIZE = 60

# 敌机类型枚举
class EnemyType(Enum):
    BASIC = 0      # 基础敌机
    FAST = 1       # 快速敌机
    TANK = 2       # 重型敌机
    SHOOTER = 3    # 射击敌机
    ZIGZAG = 4     # 蛇形敌机
    HOMING = 5     # 追踪敌机
    SPLITTER = 6   # 分裂敌机
    BOSS = 7       # BOSS

# 道具类型枚举
class PowerUpType(Enum):
    HEALTH = 0     # 生命恢复
    SHIELD = 1     # 护盾
    SPEED = 2      # 速度提升
    RAPID = 3      # 快速射击
    SPREAD = 4     # 散射
    LASER = 5      # 激光
    BOMB = 6       # 炸弹
    SCORE = 7      # 分数加倍

# 粒子类
class Particle:
    def __init__(self, x, y, color=None, particle_type="explosion"):
        self.x = x
        self.y = y
        self.type = particle_type
        
        if particle_type == "explosion":
            self.vx = random.uniform(-3, 3)
            self.vy = random.uniform(-3, 3)
            self.size = random.randint(3, 8)
            self.life = random.randint(30, 60)
            self.color = color or (random.randint(200, 255), random.randint(100, 200), 0)
            self.gravity = 0.1
        elif particle_type == "trail":
            self.vx = random.uniform(-0.5, 0.5)
            self.vy = random.uniform(-0.5, 0.5)
            self.size = random.randint(2, 4)
            self.life = random.randint(20, 40)
            self.color = color or (random.randint(100, 200), random.randint(200, 255), 255)
            self.gravity = 0.05
        elif particle_type == "star":
            self.vx = 0
            self.vy = random.uniform(1, 3)
            self.size = random.uniform(1, 3)
            self.life = 1000
            self.color = random.choice([STAR_WHITE, STAR_YELLOW])
            self.gravity = 0
        elif particle_type == "hit":
            self.vx = random.uniform(-2, 2)
            self.vy = random.uniform(-2, 2)
            self.size = random.randint(2, 5)
            self.life = random.randint(15, 30)
            self.color = (255, 100, 0)
            self.gravity = 0.2
        else:
            self.vx = random.uniform(-1, 1)
            self.vy = random.uniform(-1, 1)
            self.size = random.randint(2, 5)
            self.life = random.randint(20, 40)
            self.color = color or (255, 255, 255)
            self.gravity = 0.1
    
    def update(self):
        self.x += self.vx
        self.y += self.vy
        self.vy += self.gravity
        self.life -= 1
        
        if self.type == "star":
            # 星星闪烁
            self.size = self.size + math.sin(pygame.time.get_ticks() * 0.01) * 0.5
        
        return self.life > 0
    
    def draw(self, screen):
        alpha = min(255, self.life * 8)
        if self.type == "trail":
            # 轨迹粒子有拖尾效果
            for i in range(3):
                trail_size = self.size * (1 - i * 0.3)
                trail_alpha = alpha * (1 - i * 0.3)
                trail_color = (*self.color[:3], int(trail_alpha))
                if hasattr(pygame, 'draw_circle_alpha'):
                    pygame.draw.circle_alpha(screen, trail_color, 
                                           (int(self.x - i * self.vx), 
                                            int(self.y - i * self.vy)), 
                                           int(trail_size))
                else:
                    # 模拟半透明
                    pygame.draw.circle(screen, self.color, 
                                     (int(self.x - i * self.vx), 
                                      int(self.y - i * self.vy)), 
                                     int(trail_size))
        else:
            pygame.draw.circle(screen, self.color, 
                             (int(self.x), int(self.y)), 
                             int(self.size))

# 子弹类
class Bullet:
    def __init__(self, x, y, vx=0, vy=-BULLET_SPEED, damage=10, bullet_type="normal"):
        self.x = x
        self.y = y
        self.vx = vx
        self.vy = vy
        self.damage = damage
        self.type = bullet_type
        self.size = BULLET_SIZE
        self.life = 100
        
        if bullet_type == "player":
            self.color = BULLET_COLOR
            self.size = 5
        elif bullet_type == "enemy":
            self.color = ENEMY_RED
            self.size = 4
        elif bullet_type == "laser":
            self.color = (0, 255, 255)
            self.size = 8
            self.life = 20
        elif bullet_type == "spread":
            self.color = (255, 150, 0)
            self.size = 4
    
    def update(self):
        self.x += self.vx
        self.y += self.vy
        self.life -= 1
        
        # 屏幕边界检测
        if (self.x < -self.size or self.x > WIDTH + self.size or
            self.y < -self.size or self.y > HEIGHT + self.size):
            return False
        return self.life > 0
    
    def draw(self, screen):
        if self.type == "laser":
            # 激光特效
            for i in range(3):
                laser_size = self.size - i * 2
                laser_alpha = 200 - i * 50
                laser_color = (*self.color[:2], 255, laser_alpha)
                pygame.draw.circle(screen, laser_color, 
                                 (int(self.x), int(self.y)), laser_size)
        else:
            pygame.draw.circle(screen, self.color, 
                             (int(self.x), int(self.y)), self.size)
            
            # 子弹光晕
            pygame.draw.circle(screen, (255, 255, 200, 100), 
                             (int(self.x), int(self.y)), self.size + 2)

# 敌机类
class Enemy:
    def __init__(self, enemy_type=EnemyType.BASIC, x=None, y=None):
        self.type = enemy_type
        self.setup_by_type()
        
        # 随机位置
        if x is None or y is None:
            self.x = random.randint(20, WIDTH - 20)
            self.y = random.randint(-100, -40)
        else:
            self.x = x
            self.y = y
        
        # 运动参数
        self.angle = 0
        self.angle_speed = random.uniform(-0.05, 0.05)
        self.wave_phase = random.uniform(0, 2 * math.pi)
        self.wave_speed = random.uniform(0.05, 0.1)
        self.wave_amplitude = random.uniform(10, 30)
        
        # 射击相关
        self.shoot_timer = 0
        self.shoot_cooldown = random.randint(60, 120)
        
        # 状态
        self.health = self.max_health
        self.active = True
        self.hit_flash = 0
        self.particles = []
        
        # 特殊能力
        if self.type == EnemyType.HOMING:
            self.homing_strength = 0.05
        
        if self.type == EnemyType.SPLITTER:
            self.split_count = 2
    
    def setup_by_type(self):
        """根据敌机类型设置属性"""
        if self.type == EnemyType.BASIC:
            self.size = 20
            self.speed = random.uniform(ENEMY_SPEED_MIN, ENEMY_SPEED_MAX)
            self.max_health = 20
            self.score = 10
            self.color = ENEMY_RED
            self.shoot_chance = 0.0
        
        elif self.type == EnemyType.FAST:
            self.size = 15
            self.speed = random.uniform(3, 5)
            self.max_health = 15
            self.score = 15
            self.color = ENEMY_BLUE
            self.shoot_chance = 0.0
        
        elif self.type == EnemyType.TANK:
            self.size = 30
            self.speed = random.uniform(0.5, 1.5)
            self.max_health = 50
            self.score = 30
            self.color = ENEMY_GREEN
            self.shoot_chance = 0.0
        
        elif self.type == EnemyType.SHOOTER:
            self.size = 18
            self.speed = random.uniform(1, 2)
            self.max_health = 25
            self.score = 20
            self.color = ENEMY_PURPLE
            self.shoot_chance = 0.3
            self.shoot_cooldown = 90
        
        elif self.type == EnemyType.ZIGZAG:
            self.size = 16
            self.speed = random.uniform(2, 3)
            self.max_health = 18
            self.score = 15
            self.color = (255, 150, 50)
            self.shoot_chance = 0.0
        
        elif self.type == EnemyType.HOMING:
            self.size = 22
            self.speed = random.uniform(1, 2)
            self.max_health = 30
            self.score = 25
            self.color = (255, 100, 200)
            self.shoot_chance = 0.1
        
        elif self.type == EnemyType.SPLITTER:
            self.size = 24
            self.speed = random.uniform(1.5, 2.5)
            self.max_health = 35
            self.score = 20
            self.color = (150, 255, 150)
            self.shoot_chance = 0.0
        
        elif self.type == EnemyType.BOSS:
            self.size = BOSS_SIZE
            self.speed = 0.5
            self.max_health = BOSS_HEALTH
            self.score = 500
            self.color = BOSS_COLOR
            self.shoot_chance = 0.5
            self.shoot_cooldown = 30
    
    def update(self, player_x=None, player_y=None):
        if not self.active:
            return []
        
        bullets = []
        
        # 更新位置
        if self.type == EnemyType.ZIGZAG:
            # 蛇形移动
            self.wave_phase += self.wave_speed
            self.x += math.sin(self.wave_phase) * 2
            self.y += self.speed
        
        elif self.type == EnemyType.HOMING and player_x is not None and player_y is not None:
            # 追踪玩家
            dx = player_x - self.x
            dy = player_y - self.y
            distance = math.sqrt(dx*dx + dy*dy)
            
            if distance > 0:
                dx, dy = dx/distance, dy/distance
            
            self.x += dx * self.speed * self.homing_strength
            self.y += self.speed
        
        else:
            # 直线或轻微晃动移动
            self.angle += self.angle_speed
            self.x += math.sin(self.angle) * 0.5
            self.y += self.speed
        
        # 更新射击计时器
        self.shoot_timer += 1
        
        # 尝试射击
        if random.random() < self.shoot_chance and self.shoot_timer >= self.shoot_cooldown:
            bullets.extend(self.shoot())
            self.shoot_timer = 0
        
        # 屏幕边界检测
        if (self.y > HEIGHT + 50 or self.x < -50 or self.x > WIDTH + 50):
            self.active = False
        
        # 更新闪烁效果
        if self.hit_flash > 0:
            self.hit_flash -= 1
        
        # 更新粒子
        self.particles = [p for p in self.particles if p.update()]
        
        return bullets
    
    def shoot(self):
        """敌机射击"""
        bullets = []
        
        if self.type == EnemyType.SHOOTER:
            # 射击敌机：向下射击
            bullets.append(Bullet(self.x, self.y + self.size, 
                                0, 3, 5, "enemy"))
        
        elif self.type == EnemyType.BOSS:
            # BOSS：多重射击
            for angle in [0, math.pi/4, math.pi/2, 3*math.pi/4, math.pi, 
                         5*math.pi/4, 3*math.pi/2, 7*math.pi/4]:
                vx = math.cos(angle) * 3
                vy = math.sin(angle) * 3
                bullets.append(Bullet(self.x, self.y + self.size, 
                                    vx, vy, 10, "enemy"))
        
        elif self.type == EnemyType.HOMING:
            # 追踪敌机：向玩家方向射击
            bullets.append(Bullet(self.x, self.y + self.size, 
                                0, 4, 8, "enemy"))
        
        return bullets
    
    def take_damage(self, damage):
        """受到伤害"""
        self.health -= damage
        self.hit_flash = 5
        
        # 击中粒子效果
        for _ in range(5):
            self.particles.append(Particle(
                self.x + random.uniform(-10, 10),
                self.y + random.uniform(-10, 10),
                (255, 100, 0),
                "hit"
            ))
        
        if self.health <= 0:
            self.destroy()
            return True
        return False
    
    def destroy(self):
        """销毁敌机"""
        self.active = False
        
        # 爆炸粒子效果
        for _ in range(20):
            self.particles.append(Particle(
                self.x + random.uniform(-15, 15),
                self.y + random.uniform(-15, 15),
                self.color,
                "explosion"
            ))
    
    def draw(self, screen):
        if not self.active:
            return
        
        # 绘制粒子
        for particle in self.particles:
            particle.draw(screen)
        
        # 闪烁效果
        if self.hit_flash > 0 and (pygame.time.get_ticks() // 100) % 2 == 0:
            draw_color = (255, 255, 255)
        else:
            draw_color = self.color
        
        # 绘制敌机主体
        if self.type == EnemyType.BOSS:
            # BOSS特殊绘制
            self.draw_boss(screen, draw_color)
        else:
            self.draw_normal(screen, draw_color)
        
        # 绘制生命条
        if self.max_health > 20:  # 只对高生命值敌机显示生命条
            health_width = 40
            health_height = 4
            health_x = self.x - health_width // 2
            health_y = self.y - self.size - 10
            
            # 背景
            pygame.draw.rect(screen, (50, 50, 50), 
                           (health_x, health_y, health_width, health_height))
            
            # 生命值
            health_percent = self.health / self.max_health
            health_fill = int(health_width * health_percent)
            health_color = (0, 255, 0) if health_percent > 0.5 else (255, 255, 0) if health_percent > 0.25 else (255, 0, 0)
            pygame.draw.rect(screen, health_color, 
                           (health_x, health_y, health_fill, health_height))
    
    def draw_normal(self, screen, color):
        """绘制普通敌机"""
        # 敌机主体
        pygame.draw.polygon(screen, color, [
            (self.x, self.y - self.size),  # 上顶点
            (self.x - self.size, self.y + self.size // 2),  # 左下
            (self.x, self.y),  # 中心
            (self.x + self.size, self.y + self.size // 2)  # 右下
        ])
        
        # 敌机细节
        detail_color = (min(255, color[0] + 50), 
                       min(255, color[1] + 50), 
                       min(255, color[2] + 50))
        
        # 绘制驾驶舱
        pygame.draw.circle(screen, detail_color, 
                         (int(self.x), int(self.y - self.size // 3)), 
                         self.size // 3)
        
        # 绘制武器
        if self.type == EnemyType.SHOOTER or self.type == EnemyType.BOSS:
            pygame.draw.rect(screen, detail_color, 
                           (self.x - 3, self.y + self.size // 2, 6, 8))
    
    def draw_boss(self, screen, color):
        """绘制BOSS"""
        # BOSS主体
        pygame.draw.circle(screen, color, 
                         (int(self.x), int(self.y)), self.size)
        
        # BOSS细节
        detail_color = (min(255, color[0] + 50), 
                       min(255, color[1] + 50), 
                       min(255, color[2] + 50))
        
        # 绘制能量核心
        core_size = self.size // 3
        core_pulse = math.sin(pygame.time.get_ticks() * 0.01) * 2
        pygame.draw.circle(screen, (255, 255, 0), 
                         (int(self.x), int(self.y)), 
                         core_size + core_pulse)
        
        # 绘制装甲板
        for i in range(8):
            angle = i * math.pi / 4
            armor_x = self.x + math.cos(angle) * (self.size - 5)
            armor_y = self.y + math.sin(angle) * (self.size - 5)
            pygame.draw.circle(screen, detail_color, 
                             (int(armor_x), int(armor_y)), 8)
        
        # 绘制武器
        for i in range(4):
            angle = i * math.pi / 2 + pygame.time.get_ticks() * 0.001
            weapon_x = self.x + math.cos(angle) * (self.size + 10)
            weapon_y = self.y + math.sin(angle) * (self.size + 10)
            pygame.draw.rect(screen, (255, 0, 0), 
                           (weapon_x - 5, weapon_y - 5, 10, 15))

# 道具类
class PowerUp:
    def __init__(self, x, y, powerup_type=None):
        self.x = x
        self.y = y
        self.size = 15
        
        if powerup_type is None:
            self.type = random.choice(list(PowerUpType))
        else:
            self.type = powerup_type
        
        self.setup_by_type()
        self.collected = False
        self.float_offset = 0
        self.float_speed = random.uniform(0.05, 0.1)
        self.rotation = 0
        self.rotation_speed = random.uniform(-0.05, 0.05)
        
        # 磁力吸引
        self.magnet_strength = 0
        self.target_x = None
        self.target_y = None
    
    def setup_by_type(self):
        """根据道具类型设置属性"""
        if self.type == PowerUpType.HEALTH:
            self.color = (0, 255, 0)
            self.value = 20
            self.duration = 0
            self.name = "生命恢复"
        elif self.type == PowerUpType.SHIELD:
            self.color = (0, 200, 255)
            self.value = 50
            self.duration = 300
            self.name = "能量护盾"
        elif self.type == PowerUpType.SPEED:
            self.color = (255, 255, 0)
            self.value = 2
            self.duration = 400
            self.name = "速度提升"
        elif self.type == PowerUpType.RAPID:
            self.color = (255, 150, 0)
            self.value = 3
            self.duration = 500
            self.name = "快速射击"
        elif self.type == PowerUpType.SPREAD:
            self.color = (255, 0, 255)
            self.value = 5
            self.duration = 300
            self.name = "散射武器"
        elif self.type == PowerUpType.LASER:
            self.color = (0, 255, 255)
            self.value = 10
            self.duration = 200
            self.name = "激光武器"
        elif self.type == PowerUpType.BOMB:
            self.color = (255, 50, 50)
            self.value = 1
            self.duration = 0
            self.name = "清屏炸弹"
        elif self.type == PowerUpType.SCORE:
            self.color = (255, 215, 0)
            self.value = 2
            self.duration = 600
            self.name = "分数加倍"
    
    def update(self):
        """更新道具位置"""
        self.float_offset += self.float_speed
        self.rotation += self.rotation_speed
        
        # 自然下落
        self.y += 1
        
        # 磁力吸引
        if self.magnet_strength > 0 and self.target_x is not None and self.target_y is not None:
            dx = self.target_x - self.x
            dy = self.target_y - self.y
            distance = math.sqrt(dx*dx + dy*dy)
            
            if distance > 0:
                dx, dy = dx/distance, dy/distance
            
            self.x += dx * self.magnet_strength
            self.y += dy * self.magnet_strength
        
        # 屏幕边界检测
        if self.y > HEIGHT + 20 or self.x < -20 or self.x > WIDTH + 20:
            return False
        
        return True
    
    def draw(self, screen):
        """绘制道具"""
        if self.collected:
            return
        
        # 计算浮动位置
        float_y = self.y + math.sin(self.float_offset) * 5
        
        # 创建临时surface用于旋转
        temp_surface = pygame.Surface((self.size * 2, self.size * 2), pygame.SRCALPHA)
        
        # 绘制道具基础形状
        center_x, center_y = self.size, self.size
        
        if self.type == PowerUpType.HEALTH:
            # 生命：心形
            pygame.draw.polygon(temp_surface, self.color, [
                (center_x, center_y - self.size * 0.7),
                (center_x - self.size * 0.8, center_y - self.size * 0.2),
                (center_x, center_y + self.size * 0.5),
                (center_x + self.size * 0.8, center_y - self.size * 0.2)
            ])
        
        elif self.type == PowerUpType.SHIELD:
            # 护盾：圆形
            pygame.draw.circle(temp_surface, self.color, 
                             (center_x, center_y), self.size)
            pygame.draw.circle(temp_surface, (255, 255, 255), 
                             (center_x, center_y), self.size, 2)
        
        elif self.type == PowerUpType.SPEED:
            # 速度：闪电
            pygame.draw.polygon(temp_surface, self.color, [
                (center_x, center_y - self.size * 0.8),
                (center_x - self.size * 0.5, center_y + self.size * 0.2),
                (center_x, center_y),
                (center_x + self.size * 0.5, center_y + self.size * 0.8),
                (center_x, center_y + self.size * 0.3),
                (center_x - self.size * 0.5, center_y + self.size * 0.3)
            ])
        
        elif self.type == PowerUpType.RAPID:
            # 快速射击：三个点
            for i in range(3):
                dot_x = center_x + (i - 1) * self.size * 0.6
                pygame.draw.circle(temp_surface, self.color, 
                                 (int(dot_x), center_y), self.size * 0.4)
        
        elif self.type == PowerUpType.SPREAD:
            # 散射：扇形
            for i in range(5):
                angle = -math.pi/3 + i * math.pi/6
                end_x = center_x + math.cos(angle) * self.size
                end_y = center_y + math.sin(angle) * self.size
                pygame.draw.line(temp_surface, self.color,
                               (center_x, center_y), (end_x, end_y), 3)
        
        elif self.type == PowerUpType.LASER:
            # 激光：光束
            pygame.draw.rect(temp_surface, self.color,
                           (center_x - self.size * 0.2, center_y - self.size * 0.8,
                            self.size * 0.4, self.size * 1.6))
        
        elif self.type == PowerUpType.BOMB:
            # 炸弹：圆形带引线
            pygame.draw.circle(temp_surface, self.color, 
                             (center_x, center_y), self.size)
            pygame.draw.line(temp_surface, (255, 255, 255),
                           (center_x, center_y - self.size),
                           (center_x, center_y - self.size * 1.5), 2)
        
        elif self.type == PowerUpType.SCORE:
            # 分数：星形
            points = []
            for i in range(5):
                angle = i * 4 * math.pi / 5
                radius = self.size if i % 2 == 0 else self.size * 0.4
                points.append((
                    center_x + math.cos(angle) * radius,
                    center_y + math.sin(angle) * radius
                ))
            pygame.draw.polygon(temp_surface, self.color, points)
        
        # 旋转并绘制
        rotated = pygame.transform.rotate(temp_surface, math.degrees(self.rotation))
        rotated_rect = rotated.get_rect(center=(int(self.x), int(float_y)))
        screen.blit(rotated, rotated_rect.topleft)
        
        # 绘制光晕效果
        pulse = math.sin(pygame.time.get_ticks() * 0.005) * 2 + 3
        pygame.draw.circle(screen, (*self.color, 100), 
                         (int(self.x), int(float_y)), 
                         int(self.size + pulse), 1)

# 玩家类
class Player:
    def __init__(self):
        self.x = WIDTH // 2
        self.y = HEIGHT - 100
        self.size = PLAYER_SIZE
        self.speed = PLAYER_SPEED
        self.health = PLAYER_HEALTH
        self.max_health = PLAYER_HEALTH
        
        # 射击系统
        self.bullets = []
        self.shoot_cooldown = 0
        self.shoot_delay = 10
        self.bullet_damage = 10
        
        # 道具系统
        self.powerups = {}
        self.shield_active = False
        self.shield_strength = 0
        self.speed_boost = 1.0
        self.rapid_fire = 1
        self.spread_shot = False
        self.laser_shot = False
        self.bomb_count = 0
        self.score_multiplier = 1
        
        # 状态
        self.invincible = 0
        self.is_alive = True
        
        # 视觉效果
        self.trail = []
        self.particles = []
        self.animation_timer = 0
        
    def update(self, keys):
        if not self.is_alive:
            return
        
        # 保存旧位置用于轨迹
        old_x, old_y = self.x, self.y
        
        # 处理移动输入
        move_speed = self.speed * self.speed_boost
        
        if keys[pygame.K_LEFT] or keys[pygame.K_a]:
            self.x -= move_speed
        if keys[pygame.K_RIGHT] or keys[pygame.K_d]:
            self.x += move_speed
        if keys[pygame.K_UP] or keys[pygame.K_w]:
            self.y -= move_speed
        if keys[pygame.K_DOWN] or keys[pygame.K_s]:
            self.y += move_speed
        
        # 边界检查
        self.x = max(self.size, min(self.x, WIDTH - self.size))
        self.y = max(self.size, min(self.y, HEIGHT - self.size))
        
        # 添加轨迹点
        if (old_x != self.x or old_y != self.y) and len(self.trail) < 10:
            self.trail.insert(0, (self.x, self.y))
        
        # 限制轨迹长度
        if len(self.trail) > 10:
            self.trail.pop()
        
        # 更新轨迹粒子
        for i, (trail_x, trail_y) in enumerate(self.trail):
            if random.random() < 0.3:
                self.particles.append(Particle(
                    trail_x + random.uniform(-5, 5),
                    trail_y + random.uniform(-5, 5),
                    PLAYER_TRAIL[:3],
                    "trail"
                ))
        
        # 处理射击
        if keys[pygame.K_SPACE] or keys[pygame.K_j]:
            self.shoot()
        
        # 使用炸弹
        if keys[pygame.K_b] and self.bomb_count > 0:
            self.use_bomb()
        
        # 更新射击冷却
        if self.shoot_cooldown > 0:
            self.shoot_cooldown -= 1
        
        # 更新无敌时间
        if self.invincible > 0:
            self.invincible -= 1
        
        # 更新道具效果
        self.update_powerups()
        
        # 更新子弹
        self.bullets = [b for b in self.bullets if b.update()]
        
        # 更新粒子
        self.particles = [p for p in self.particles if p.update()]
        
        # 更新动画
        self.animation_timer += 1
    
    def shoot(self):
        """射击"""
        if self.shoot_cooldown > 0:
            return
        
        # 计算射击延迟
        delay = self.shoot_delay
        if self.rapid_fire > 1:
            delay = max(3, delay // self.rapid_fire)
        
        self.shoot_cooldown = delay
        
        if self.laser_shot:
            # 激光射击
            self.bullets.append(Bullet(
                self.x, self.y - self.size,
                0, -10, self.bullet_damage * 2, "laser"
            ))
            
        elif self.spread_shot:
            # 散射射击
            for angle in [-0.3, -0.15, 0, 0.15, 0.3]:
                vx = math.sin(angle) * 2
                vy = -BULLET_SPEED
                self.bullets.append(Bullet(
                    self.x, self.y - self.size,
                    vx, vy, self.bullet_damage, "spread"
                ))
                
        else:
            # 普通射击
            self.bullets.append(Bullet(
                self.x, self.y - self.size,
                0, -BULLET_SPEED, self.bullet_damage, "player"
            ))
    
    def use_bomb(self):
        """使用炸弹"""
        self.bomb_count -= 1
        
        # 炸弹粒子效果
        for _ in range(50):
            self.particles.append(Particle(
                self.x + random.uniform(-100, 100),
                self.y + random.uniform(-100, 100),
                (255, 200, 0),
                "explosion"
            ))
    
    def update_powerups(self):
        """更新道具效果"""
        # 更新护盾
        if self.shield_active:
            self.shield_strength -= 1
            if self.shield_strength <= 0:
                self.shield_active = False
        
        # 更新其他道具持续时间
        expired = []
        for powerup_type, duration in self.powerups.items():
            if duration > 0:
                self.powerups[powerup_type] = duration - 1
            else:
                expired.append(powerup_type)
        
        # 移除过期的道具效果
        for powerup_type in expired:
            self.remove_powerup(powerup_type)
    
    def add_powerup(self, powerup):
        """获得道具"""
        if powerup.type == PowerUpType.HEALTH:
            self.health = min(self.max_health, self.health + powerup.value)
            
        elif powerup.type == PowerUpType.SHIELD:
            self.shield_active = True
            self.shield_strength = powerup.duration
            
        elif powerup.type == PowerUpType.SPEED:
            self.speed_boost = powerup.value
            self.powerups[powerup.type] = powerup.duration
            
        elif powerup.type == PowerUpType.RAPID:
            self.rapid_fire = powerup.value
            self.powerups[powerup.type] = powerup.duration
            
        elif powerup.type == PowerUpType.SPREAD:
            self.spread_shot = True
            self.powerups[powerup.type] = powerup.duration
            
        elif powerup.type == PowerUpType.LASER:
            self.laser_shot = True
            self.powerups[powerup.type] = powerup.duration
            
        elif powerup.type == PowerUpType.BOMB:
            self.bomb_count += powerup.value
            
        elif powerup.type == PowerUpType.SCORE:
            self.score_multiplier = powerup.value
            self.powerups[powerup.type] = powerup.duration
    
    def remove_powerup(self, powerup_type):
        """移除道具效果"""
        if powerup_type == PowerUpType.SPEED:
            self.speed_boost = 1.0
        elif powerup_type == PowerUpType.RAPID:
            self.rapid_fire = 1
        elif powerup_type == PowerUpType.SPREAD:
            self.spread_shot = False
        elif powerup_type == PowerUpType.LASER:
            self.laser_shot = False
        elif powerup_type == PowerUpType.SCORE:
            self.score_multiplier = 1
        
        if powerup_type in self.powerups:
            del self.powerups[powerup_type]
    
    def take_damage(self, damage):
        """受到伤害"""
        if self.invincible > 0 or not self.is_alive:
            return False
        
        # 护盾抵消伤害
        if self.shield_active:
            self.shield_strength -= damage * 5
            if self.shield_strength <= 0:
                self.shield_active = False
            return False
        
        self.health -= damage
        self.invincible = 30
        
        # 受伤粒子效果
        for _ in range(20):
            self.particles.append(Particle(
                self.x + random.uniform(-10, 10),
                self.y + random.uniform(-10, 10),
                (255, 50, 50),
                "explosion"
            ))
        
        if self.health <= 0:
            self.destroy()
            return True
        
        return False
    
    def destroy(self):
        """玩家被摧毁"""
        self.is_alive = False
        
        # 大爆炸粒子效果
        for _ in range(100):
            self.particles.append(Particle(
                self.x + random.uniform(-30, 30),
                self.y + random.uniform(-30, 30),
                (255, 100, 0),
                "explosion"
            ))
    
    def draw(self, screen):
        """绘制玩家"""
        if not self.is_alive:
            return
        
        # 绘制粒子
        for particle in self.particles:
            particle.draw(screen)
        
        # 绘制轨迹
        for i, (trail_x, trail_y) in enumerate(self.trail):
            alpha = 255 * (1 - i / len(self.trail))
            size = self.size * (1 - i / len(self.trail)) * 0.5
            pygame.draw.circle(screen, (*PLAYER_TRAIL[:3], int(alpha)), 
                             (int(trail_x), int(trail_y)), int(size))
        
        # 无敌闪烁效果
        if self.invincible > 0 and (pygame.time.get_ticks() // 100) % 2 == 0:
            return
        
        # 绘制玩家飞船
        self.draw_ship(screen)
        
        # 绘制护盾
        if self.shield_active:
            shield_size = self.size + 5
            shield_alpha = 100 + int(math.sin(pygame.time.get_ticks() * 0.01) * 50)
            shield_strength_percent = self.shield_strength / 300
            shield_color = (0, int(200 * shield_strength_percent), 255, shield_alpha)
            
            pygame.draw.circle(screen, shield_color, 
                             (int(self.x), int(self.y)), shield_size, 3)
    
    def draw_ship(self, screen):
        """绘制飞船"""
        # 飞船主体
        points = [
            (self.x, self.y - self.size),  # 上顶点
            (self.x - self.size, self.y + self.size),  # 左下
            (self.x, self.y + self.size // 2),  # 中心下
            (self.x + self.size, self.y + self.size)  # 右下
        ]
        
        # 飞船颜色
        ship_color = PLAYER_COLOR
        if self.invincible > 0:
            # 无敌时闪烁
            ship_color = (255, 255, 255) if (pygame.time.get_ticks() // 50) % 2 == 0 else PLAYER_COLOR
        
        pygame.draw.polygon(screen, ship_color, points)
        
        # 飞船细节
        detail_color = (min(255, ship_color[0] + 50), 
                       min(255, ship_color[1] + 50), 
                       min(255, ship_color[2] + 50))
        
        # 驾驶舱
        pygame.draw.circle(screen, detail_color, 
                         (int(self.x), int(self.y - self.size // 3)), 
                         self.size // 3)
        
        # 引擎火焰
        flame_height = 8 + math.sin(pygame.time.get_ticks() * 0.05) * 3
        flame_points = [
            (self.x - self.size // 2, self.y + self.size),
            (self.x, self.y + self.size + flame_height),
            (self.x + self.size // 2, self.y + self.size)
        ]
        pygame.draw.polygon(screen, (255, 100, 0), flame_points)
        
        # 引擎粒子
        if random.random() < 0.5:
            self.particles.append(Particle(
                self.x + random.uniform(-3, 3),
                self.y + self.size + 5,
                (255, 150, 0),
                "trail"
            ))
    
    def draw_bullets(self, screen):
        """绘制子弹"""
        for bullet in self.bullets:
            bullet.draw(screen)

# 游戏主类
class FlightDodgeGame:
    def __init__(self):
        self.player = Player()
        self.enemies = []
        self.powerups = []
        self.stars = []
        self.score = 0
        self.high_score = 0
        self.wave = 1
        self.wave_timer = 0
        self.game_state = "playing"  # playing, game_over, pause
        self.particles = []
        
        # 生成星星背景
        self.generate_stars()
        
        # 字体
        self.font_large = pygame.font.Font(None, 48)
        self.font_medium = pygame.font.Font(None, 32)
        self.font_small = pygame.font.Font(None, 24)
        
        # 加载音效（占位）
        self.load_sounds()
    
    def load_sounds(self):
        """加载音效"""
        pass
    
    def generate_stars(self):
        """生成星星背景"""
        for _ in range(STAR_COUNT):
            self.stars.append(Particle(
                random.randint(0, WIDTH),
                random.randint(0, HEIGHT),
                None, "star"
            ))
    
    def spawn_enemy(self, enemy_type=None, x=None, y=None):
        """生成敌机"""
        if enemy_type is None:
            # 根据波次选择敌机类型
            enemy_weights = self.get_enemy_weights()
            enemy_types = list(EnemyType)
            enemy_types.remove(EnemyType.BOSS)  # BOSS特殊生成
            enemy_type = random.choices(enemy_types, weights=enemy_weights[:7], k=1)[0]
        
        enemy = Enemy(enemy_type, x, y)
        self.enemies.append(enemy)
        return enemy
    
    def get_enemy_weights(self):
        """获取敌机生成权重"""
        base_weights = [30, 20, 10, 15, 10, 5, 5, 0]  # 基础权重
        
        # 随波次调整权重
        if self.wave > 5:
            base_weights[0] -= 5  # 减少基础敌机
            base_weights[2] += 5  # 增加重型敌机
            base_weights[3] += 5  # 增加射击敌机
        
        if self.wave > 10:
            base_weights[5] += 5  # 增加追踪敌机
            base_weights[6] += 5  # 增加分裂敌机
        
        return base_weights
    
    def spawn_powerup(self, x, y, powerup_type=None):
        """生成道具"""
        powerup = PowerUp(x, y, powerup_type)
        self.powerups.append(powerup)
        return powerup
    
    def spawn_wave(self):
        """生成一波敌机"""
        enemy_count = min(10 + self.wave * 2, 30)  # 限制最大数量
        
        for _ in range(enemy_count):
            x = random.randint(50, WIDTH - 50)
            y = random.randint(-200, -50)
            self.spawn_enemy(x=x, y=y)
        
        # 每5波生成一个BOSS
        if self.wave % 5 == 0:
            self.spawn_enemy(EnemyType.BOSS, WIDTH // 2, -100)
        
        self.wave_timer = WAVE_DURATION
    
    def update(self):
        if self.game_state != "playing":
            return
        
        # 获取按键
        keys = pygame.key.get_pressed()
        
        # 更新玩家
        self.player.update(keys)
        
        # 如果玩家死亡，游戏结束
        if not self.player.is_alive:
            self.game_state = "game_over"
            self.high_score = max(self.high_score, self.score)
            return
        
        # 更新星星
        for star in self.stars:
            if not star.update():
                # 重置星星位置
                star.x = random.randint(0, WIDTH)
                star.y = 0
                star.vy = random.uniform(1, 3)
        
        # 更新敌机
        active_enemies = []
        for enemy in self.enemies:
            bullets = enemy.update(self.player.x, self.player.y)
            
            # 添加敌机子弹
            for bullet in bullets:
                bullet.type = "enemy"
                self.player.bullets.append(bullet)
            
            if enemy.active:
                active_enemies.append(enemy)
                
                # 检查敌机与玩家碰撞
                if self.check_collision(enemy, self.player):
                    if self.player.take_damage(20):
                        self.game_state = "game_over"
                        self.high_score = max(self.high_score, self.score)
                        return
                    
                    # 敌机对玩家造成伤害后爆炸
                    enemy.destroy()
                
                # 检查敌机与玩家子弹碰撞
                for bullet in self.player.bullets[:]:
                    if bullet.type == "player" and self.check_collision(enemy, bullet):
                        if enemy.take_damage(bullet.damage):
                            # 敌机被摧毁
                            self.score += enemy.score * self.player.score_multiplier
                            
                            # 一定概率掉落道具
                            if random.random() < 0.2:
                                self.spawn_powerup(enemy.x, enemy.y)
                            
                            # 分裂敌机分裂
                            if enemy.type == EnemyType.SPLITTER:
                                for _ in range(enemy.split_count):
                                    self.spawn_enemy(EnemyType.BASIC, enemy.x, enemy.y)
                        
                        # 移除子弹
                        if bullet in self.player.bullets:
                            self.player.bullets.remove(bullet)
                        
                        break
        
        self.enemies = active_enemies
        
        # 更新道具
        active_powerups = []
        for powerup in self.powerups:
            # 设置磁力目标
            if self.player.powerups.get(PowerUpType.SCORE, 0) > 0:
                powerup.magnet_strength = 3
                powerup.target_x = self.player.x
                powerup.target_y = self.player.y
            
            if powerup.update():
                # 检查道具与玩家碰撞
                if self.check_collision(powerup, self.player) and not powerup.collected:
                    self.player.add_powerup(powerup)
                    powerup.collected = True
                    self.score += 50 * self.player.score_multiplier
                else:
                    active_powerups.append(powerup)
        
        self.powerups = active_powerups
        
        # 检查敌机子弹与玩家碰撞
        for bullet in self.player.bullets[:]:
            if bullet.type == "enemy" and self.check_collision(bullet, self.player):
                if self.player.take_damage(bullet.damage):
                    self.game_state = "game_over"
                    self.high_score = max(self.high_score, self.score)
                    return
                
                if bullet in self.player.bullets:
                    self.player.bullets.remove(bullet)
        
        # 更新波次
        if self.wave_timer > 0:
            self.wave_timer -= 1
        else:
            self.wave += 1
            self.spawn_wave()
        
        # 更新粒子
        self.particles = [p for p in self.particles if p.update()]
    
    def check_collision(self, obj1, obj2):
        """检查两个物体是否碰撞"""
        if hasattr(obj1, 'size') and hasattr(obj2, 'size'):
            dx = obj1.x - obj2.x
            dy = obj1.y - obj2.y
            distance = math.sqrt(dx*dx + dy*dy)
            
            size1 = obj1.size if hasattr(obj1, 'size') else 0
            size2 = obj2.size if hasattr(obj2, 'size') else 0
            
            return distance < (size1 + size2)
        
        return False
    
    def handle_event(self, event):
        """处理事件"""
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_r and self.game_state == "game_over":
                self.__init__()  # 重新开始游戏
            elif event.key == pygame.K_p:
                self.game_state = "pause" if self.game_state == "playing" else "playing"
            elif event.key == pygame.K_ESCAPE:
                pygame.quit()
                sys.exit()
    
    def draw(self, screen):
        """绘制游戏"""
        # 绘制星空背景
        screen.fill(SPACE_BLACK)
        
        # 绘制星云效果
        self.draw_nebula(screen)
        
        # 绘制星星
        for star in self.stars:
            star.draw(screen)
        
        # 绘制敌机
        for enemy in self.enemies:
            enemy.draw(screen)
        
        # 绘制道具
        for powerup in self.powerups:
            powerup.draw(screen)
        
        # 绘制玩家子弹
        self.player.draw_bullets(screen)
        
        # 绘制玩家
        self.player.draw(screen)
        
        # 绘制粒子
        for particle in self.particles:
            particle.draw(screen)
        
        # 绘制UI
        self.draw_ui(screen)
        
        # 绘制游戏结束画面
        if self.game_state == "game_over":
            self.draw_game_over(screen)
        elif self.game_state == "pause":
            self.draw_pause(screen)
    
    def draw_nebula(self, screen):
        """绘制星云效果"""
        # 创建半透明的星云表面
        nebula_surface = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)
        
        # 绘制多个圆形星云
        for i in range(3):
            center_x = WIDTH // 2 + math.sin(pygame.time.get_ticks() * 0.0001 + i) * 100
            center_y = HEIGHT // 2 + math.cos(pygame.time.get_ticks() * 0.0001 + i) * 100
            radius = 150 + i * 50
            
            # 使用渐变色绘制星云
            for r in range(radius, 0, -10):
                alpha = int(30 * (1 - r / radius))
                color = (*NEBULA_PURPLE[:3], alpha) if i % 2 == 0 else (*NEBULA_BLUE[:3], alpha)
                pygame.draw.circle(nebula_surface, color, 
                                 (int(center_x), int(center_y)), r)
        
        screen.blit(nebula_surface, (0, 0))
    
    def draw_ui(self, screen):
        """绘制用户界面"""
        # 绘制分数
        score_text = self.font_medium.render(f"分数: {self.score}", True, TEXT_WHITE)
        screen.blit(score_text, (20, 20))
        
        # 绘制最高分
        high_score_text = self.font_small.render(f"最高分: {self.high_score}", True, TEXT_GOLD)
        screen.blit(high_score_text, (20, 50))
        
        # 绘制波次
        wave_text = self.font_medium.render(f"波次: {self.wave}", True, TEXT_GREEN)
        screen.blit(wave_text, (WIDTH - 120, 20))
        
        # 绘制波次计时器
        if self.wave_timer > 0:
            wave_time = self.wave_timer // 60
            wave_timer_text = self.font_small.render(f"下一波: {wave_time}s", True, TEXT_WHITE)
            screen.blit(wave_timer_text, (WIDTH - 120, 50))
        
        # 绘制生命条
        health_width = 200
        health_height = 20
        health_x = WIDTH // 2 - health_width // 2
        health_y = 20
        
        # 生命条背景
        pygame.draw.rect(screen, (50, 50, 50), 
                       (health_x, health_y, health_width, health_height), border_radius=5)
        
        # 生命值填充
        health_percent = self.player.health / self.player.max_health
        health_fill = int(health_width * health_percent)
        
        if health_percent > 0.5:
            health_color = HEALTH_COLOR
        elif health_percent > 0.25:
            health_color = HEALTH_MID
        else:
            health_color = HEALTH_LOW
        
        pygame.draw.rect(screen, health_color, 
                       (health_x, health_y, health_fill, health_height), border_radius=5)
        
        # 生命条边框
        pygame.draw.rect(screen, (200, 200, 200), 
                       (health_x, health_y, health_width, health_height), 2, border_radius=5)
        
        # 生命值文字
        health_text = self.font_small.render(f"{self.player.health}/{self.player.max_health}", 
                                           True, TEXT_WHITE)
        screen.blit(health_text, (health_x + health_width // 2 - health_text.get_width() // 2, 
                                health_y + health_height // 2 - health_text.get_height() // 2))
        
        # 绘制道具状态
        y_offset = 60
        if self.player.powerups or self.player.bomb_count > 0 or self.player.shield_active:
            # 道具标题
            powerup_title = self.font_small.render("道具状态:", True, TEXT_WHITE)
            screen.blit(powerup_title, (WIDTH // 2 - 50, y_offset))
            y_offset += 25
            
            # 绘制激活的道具
            active_powerups = []
            
            if self.player.shield_active:
                active_powerups.append(("护盾", self.player.shield_strength, (0, 200, 255)))
            
            if self.player.bomb_count > 0:
                active_powerups.append((f"炸弹×{self.player.bomb_count}", 0, (255, 50, 50)))
            
            for powerup_type, duration in self.player.powerups.items():
                if duration > 0:
                    if powerup_type == PowerUpType.SPEED:
                        active_powerups.append(("加速", duration, (255, 255, 0)))
                    elif powerup_type == PowerUpType.RAPID:
                        active_powerups.append(("速射", duration, (255, 150, 0)))
                    elif powerup_type == PowerUpType.SPREAD:
                        active_powerups.append(("散射", duration, (255, 0, 255)))
                    elif powerup_type == PowerUpType.LASER:
                        active_powerups.append(("激光", duration, (0, 255, 255)))
                    elif powerup_type == PowerUpType.SCORE:
                        active_powerups.append(("双倍分", duration, (255, 215, 0)))
            
            # 绘制道具条
            for i, (name, duration, color) in enumerate(active_powerups[:4]):  # 最多显示4个
                bar_width = 80
                bar_height = 15
                bar_x = WIDTH // 2 - 100 + (i % 2) * 110
                bar_y = y_offset + (i // 2) * 25
                
                # 背景
                pygame.draw.rect(screen, (50, 50, 50), 
                               (bar_x, bar_y, bar_width, bar_height), border_radius=3)
                
                # 持续时间条
                if duration > 0:
                    duration_percent = duration / 300  # 假设最大持续300帧
                    fill_width = max(2, int(bar_width * duration_percent))
                    pygame.draw.rect(screen, color, 
                                   (bar_x, bar_y, fill_width, bar_height), border_radius=3)
                
                # 边框
                pygame.draw.rect(screen, (200, 200, 200), 
                               (bar_x, bar_y, bar_width, bar_height), 1, border_radius=3)
                
                # 道具名称
                name_text = self.font_small.render(name, True, TEXT_WHITE)
                screen.blit(name_text, (bar_x + bar_width // 2 - name_text.get_width() // 2, 
                                      bar_y - 15))
        
        # 绘制控制提示
        controls = [
            "控制: WASD/方向键移动, 空格/J射击, B炸弹, P暂停, R重玩, ESC退出"
        ]
        
        for i, text in enumerate(controls):
            control_text = self.font_small.render(text, True, (200, 200, 200))
            screen.blit(control_text, (WIDTH//2 - control_text.get_width()//2, HEIGHT - 25))
    
    def draw_game_over(self, screen):
        """绘制游戏结束画面"""
        overlay = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)
        overlay.fill((0, 0, 0, 150))
        screen.blit(overlay, (0, 0))
        
        # 游戏结束文字
        game_over_text = self.font_large.render("游戏结束!", True, TEXT_RED)
        final_score_text = self.font_medium.render(f"最终分数: {self.score}", True, TEXT_WHITE)
        high_score_text = self.font_medium.render(f"最高记录: {self.high_score}", True, TEXT_GOLD)
        wave_text = self.font_medium.render(f"到达波次: {self.wave}", True, TEXT_GREEN)
        restart_text = self.font_medium.render("按 R 键重新开始", True, (100, 255, 100))
        
        texts = [game_over_text, final_score_text, high_score_text, wave_text, restart_text]
        y_start = HEIGHT // 2 - len(texts) * 20
        
        for i, text in enumerate(texts):
            screen.blit(text, (WIDTH//2 - text.get_width()//2, y_start + i * 50))
    
    def draw_pause(self, screen):
        """绘制暂停画面"""
        overlay = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)
        overlay.fill((0, 0, 0, 150))
        screen.blit(overlay, (0, 0))
        
        # 暂停文字
        pause_text = self.font_large.render("游戏暂停", True, TEXT_WHITE)
        continue_text = self.font_medium.render("按 P 键继续游戏", True, TEXT_GREEN)
        
        screen.blit(pause_text, (WIDTH//2 - pause_text.get_width()//2, HEIGHT//2 - 50))
        screen.blit(continue_text, (WIDTH//2 - continue_text.get_width()//2, HEIGHT//2 + 20))

# 主函数
def main():
    game = FlightDodgeGame()
    
    # 生成第一波敌机
    game.spawn_wave()
    
    # 主循环
    running = True
    while running:
        # 处理事件
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            else:
                game.handle_event(event)
        
        # 更新游戏
        if game.game_state == "playing":
            game.update()
        
        # 绘制游戏
        game.draw(screen)
        
        # 更新显示
        pygame.display.flip()
        clock.tick(60)
    
    pygame.quit()
    sys.exit()

if __name__ == "__main__":
    main()