import pygame
import random
import math
import sys

# --- 配置区 ---
WIDTH, HEIGHT = 600, 800
FPS = 60

# 颜色
WHITE = (255, 255, 255)
BLACK = (20, 20, 30)
CYAN = (0, 255, 255)
MAGENTA = (255, 0, 255)
GOLD = (255, 215, 0)
RED = (255, 50, 50)
GREEN = (50, 255, 50)

# 皮肤配置 (颜色, 尾焰颜色, 名称)
SKINS = [
    {"color": CYAN, "trail": (0, 100, 255), "name": "蓝焰战机"},
    {"color": MAGENTA, "trail": (255, 0, 100), "name": "霓虹幻影"},
    {"color": GOLD, "trail": (255, 100, 0), "name": "黄金猎鹰"},
    {"color": GREEN, "trail": (0, 255, 100), "name": "翡翠风暴"},
]

# 障碍物类型
OBSTACLE_TYPES = [
    {"type": "block", "color": (100, 100, 120), "w": 60, "h": 40},
    {"type": "spike", "color": RED, "w": 40, "h": 50},
    {"type": "wide", "color": (80, 80, 100), "w": 150, "h": 30},
]

class Particle:
    def __init__(self, x, y, color, is_explosion=False):
        self.x = x
        self.y = y
        self.color = color
        if is_explosion:
            angle = random.uniform(0, 2 * math.pi)
            speed = random.uniform(2, 8)
            self.vx = math.cos(angle) * speed
            self.vy = math.sin(angle) * speed
            self.life = random.randint(20, 40)
            self.size = random.randint(2, 5)
        else:
            self.vx = random.uniform(-1, 1)
            self.vy = random.uniform(2, 5)
            self.life = random.randint(10, 20)
            self.size = random.randint(1, 3)
        self.max_life = self.life

    def update(self):
        self.x += self.vx
        self.y += self.vy
        self.life -= 1
        if self.max_life > 30:  # 爆炸粒子减速
            self.vx *= 0.95
            self.vy *= 0.95

    def draw(self, surface):
        alpha = max(0, self.life / self.max_life)
        r = max(1, int(self.size * alpha))
        pygame.draw.circle(surface, self.color, (int(self.x), int(self.y)), r)

class Player:
    def __init__(self):
        self.skin_idx = 0
        self.w = 40
        self.h = 50
        self.x = WIDTH // 2
        self.y = HEIGHT - 100
        self.speed = 8
        self.shield = False
        self.shield_timer = 0

    @property
    def skin(self):
        return SKINS[self.skin_idx]

    def update(self, keys):
        if keys[pygame.K_LEFT] or keys[pygame.K_a]: self.x -= self.speed
        if keys[pygame.K_RIGHT] or keys[pygame.K_d]: self.x += self.speed
        if keys[pygame.K_UP] or keys[pygame.K_w]: self.y -= self.speed
        if keys[pygame.K_DOWN] or keys[pygame.K_s]: self.y += self.speed
        
        # 边界
        self.x = max(0, min(WIDTH - self.w, self.x))
        self.y = max(0, min(HEIGHT - self.h, self.y))

        if self.shield:
            self.shield_timer -= 1
            if self.shield_timer <= 0: self.shield = False

    def draw(self, surface, particles):
        # 尾焰特效
        if random.random() < 0.6:
            particles.append(Particle(
                self.x + self.w//2 + random.randint(-5, 5),
                self.y + self.h,
                self.skin["trail"]
            ))
        
        # 飞机本体 (简单多边形)
        points = [
            (self.x + self.w//2, self.y),
            (self.x, self.y + self.h),
            (self.x + self.w//2, self.y + self.h - 10),
            (self.x + self.w, self.y + self.h)
        ]
        pygame.draw.polygon(surface, self.skin["color"], points)
        pygame.draw.polygon(surface, WHITE, points, 2)

        # 护盾特效
        if self.shield:
            pygame.draw.circle(surface, CYAN, (int(self.x + self.w//2), int(self.y + self.h//2)), 35, 2)

    def get_rect(self):
        return pygame.Rect(self.x + 5, self.y + 5, self.w - 10, self.h - 10)

class Obstacle:
    def __init__(self, level):
        self.type_data = random.choice(OBSTACLE_TYPES)
        self.w = self.type_data["w"]
        self.h = self.type_data["h"]
        self.x = random.randint(0, WIDTH - self.w)
        self.y = -50
        self.speed = 3 + (level * 0.5) + random.uniform(0, 2)
        self.color = self.type_data["color"]

    def update(self):
        self.y += self.speed

    def draw(self, surface):
        if self.type_data["type"] == "spike":
            points = [
                (self.x + self.w//2, self.y + self.h),
                (self.x, self.y),
                (self.x + self.w, self.y)
            ]
            pygame.draw.polygon(surface, self.color, points)
        else:
            pygame.draw.rect(surface, self.color, (self.x, self.y, self.w, self.h))
            pygame.draw.rect(surface, WHITE, (self.x, self.y, self.w, self.h), 1)

    def get_rect(self):
        return pygame.Rect(self.x, self.y, self.w, self.h)

class Game:
    def __init__(self):
        pygame.init()
        self.screen = pygame.display.set_mode((WIDTH, HEIGHT))
        pygame.display.set_caption("✈️ 霓虹空战：无限突围")
        self.clock = pygame.time.Clock()
        self.font = pygame.font.Font(None, 36)
        self.big_font = pygame.font.Font(None, 72)
        
        self.reset_game()
        self.state = "MENU" # MENU, PLAY, GAMEOVER, SHOP

    def reset_game(self):
        self.player = Player()
        self.obstacles = []
        self.particles = []
        self.score = 0
        self.level = 1
        self.coins = 0
        self.total_coins = 0
        self.frame_count = 0
        self.mission_text = "存活 10 秒"
        self.mission_done = False
        self.spawn_rate = 40

    def spawn_obstacle(self):
        self.obstacles.append(Obstacle(self.level))

    def check_mission(self):
        if not self.mission_done:
            if self.level == 1 and self.frame_count > 600: # 10秒
                self.mission_done = True
                self.mission_text = "✅ 任务完成！+50金币"
                self.coins += 50
                self.total_coins += 50
            elif self.level > 1 and self.score > self.level * 500:
                self.mission_done = True
                self.mission_text = "✅ 突破防线！+100金币"
                self.coins += 100
                self.total_coins += 100

    def level_up(self):
        self.level += 1
        self.mission_done = False
        self.mission_text = f"第 {self.level} 关：躲避 {self.level*5} 个障碍"
        self.spawn_rate = max(15, 40 - self.level * 2)
        # 升级特效
        for _ in range(50):
            self.particles.append(Particle(WIDTH//2, HEIGHT//2, GOLD, True))

    def handle_collision(self):
        if self.player.shield:
            self.player.shield = False
            for _ in range(20):
                self.particles.append(Particle(self.player.x+20, self.player.y+25, CYAN, True))
            return False
        return True

    def draw_ui(self):
        # 分数 & 关卡
        txt = self.font.render(f"关卡: {self.level}  分数: {self.score}  💰{self.coins}", True, WHITE)
        self.screen.blit(txt, (10, 10))
        
        # 任务
        m_color = GREEN if self.mission_done else GOLD
        m_txt = self.font.render(f"任务: {self.mission_text}", True, m_color)
        self.screen.blit(m_txt, (10, 50))

        # 换肤提示
        hint = self.font.render("[TAB] 换肤  [SPACE] 护盾", True, (150,150,150))
        self.screen.blit(hint, (WIDTH - 280, HEIGHT - 30))

    def draw_menu(self):
        self.screen.fill(BLACK)
        title = self.big_font.render("霓虹空战", True, CYAN)
        sub = self.font.render("按 ENTER 开始 | TAB 换肤", True, WHITE)
        skin_name = self.font.render(f"当前: {self.player.skin['name']}", True, MAGENTA)
        
        self.screen.blit(title, (WIDTH//2 - title.get_width()//2, 200))
        self.screen.blit(sub, (WIDTH//2 - sub.get_width()//2, 300))
        self.screen.blit(skin_name, (WIDTH//2 - skin_name.get_width()//2, 350))
        pygame.display.flip()

    def run(self):
        while True:
            self.clock.tick(FPS)
            keys = pygame.key.get_pressed()

            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit(); sys.exit()
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_TAB:
                        self.player.skin_idx = (self.player.skin_idx + 1) % len(SKINS)
                    if event.key == pygame.K_SPACE and self.state == "PLAY":
                        if not self.player.shield and self.coins >= 20:
                            self.player.shield = True
                            self.player.shield_timer = 180 # 3秒
                            self.coins -= 20
                    if event.key == pygame.K_RETURN:
                        if self.state == "MENU": self.state = "PLAY"
                        elif self.state == "GAMEOVER": self.reset_game(); self.state = "PLAY"

            if self.state == "MENU":
                self.draw_menu()
                continue

            if self.state == "PLAY":
                self.screen.fill(BLACK)
                self.frame_count += 1
                self.score += 1

                # 逻辑更新
                self.player.update(keys)
                self.check_mission()

                # 生成障碍
                if self.frame_count % self.spawn_rate == 0:
                    self.spawn_obstacle()

                # 关卡判定
                if self.score > self.level * 1000 and not self.mission_done:
                    pass # 等待任务完成
                elif self.mission_done and self.score > self.level * 1200:
                    self.level_up()

                # 障碍更新 & 碰撞
                for obs in self.obstacles[:]:
                    obs.update()
                    if obs.y > HEIGHT:
                        self.obstacles.remove(obs)
                        self.coins += 1 # 躲避成功奖励
                    elif obs.get_rect().colliderect(self.player.get_rect()):
                        if self.handle_collision():
                            self.state = "GAMEOVER"
                            for _ in range(100):
                                self.particles.append(Particle(self.player.x+20, self.player.y+25, RED, True))

                # 粒子更新
                for p in self.particles[:]:
                    p.update()
                    if p.life <= 0: self.particles.remove(p)

                # 绘制
                for p in self.particles: p.draw(self.screen)
                for obs in self.obstacles: obs.draw(self.screen)
                self.player.draw(self.screen, self.particles)
                self.draw_ui()

            elif self.state == "GAMEOVER":
                # 继续渲染粒子爆炸
                self.screen.fill(BLACK)
                for p in self.particles[:]:
                    p.update()
                    p.draw(self.screen)
                    if p.life <= 0: self.particles.remove(p)
                
                txt = self.big_font.render("GAME OVER", True, RED)
                sc = self.font.render(f"最终分数: {self.score} | 总金币: {self.total_coins}", True, WHITE)
                self.screen.blit(txt, (WIDTH//2 - txt.get_width()//2, 300))
                self.screen.blit(sc, (WIDTH//2 - sc.get_width()//2, 380))

            pygame.display.flip()

if __name__ == "__main__":
    game = Game()
    game.run()