import pygame
import random
import sys
import math

# 初始化 Pygame
pygame.init()

# 游戏窗口设置
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("飞行躲避游戏 - 元宝出品")

# 颜色定义
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 50, 50)
GREEN = (50, 255, 50)
BLUE = (50, 150, 255)
YELLOW = (255, 255, 50)
PURPLE = (180, 70, 200)

# 玩家飞机类


class Player:
    def __init__(self):
        self.width = 40
        self.height = 50
        self.x = WIDTH // 2
        self.y = HEIGHT - 100
        self.speed = 6
        self.color = BLUE
        self.score = 0
        self.lives = 3
        self.invincible = False
        self.invincible_timer = 0

    def move(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.width, self.x))
        self.y = max(0, min(HEIGHT - self.height, self.y))

    def draw(self):
        # 如果无敌状态，闪烁效果
        if not self.invincible or pygame.time.get_ticks() % 200 < 100:
            # 绘制飞机主体
            pygame.draw.polygon(screen, self.color, [
                (self.x + self.width//2, self.y),  # 机头
                (self.x, self.y + self.height),    # 左下
                (self.x + self.width, self.y + self.height)  # 右下
            ])

            # 绘制机翼
            pygame.draw.polygon(screen, GREEN, [
                (self.x, self.y + self.height//3),
                (self.x - 15, self.y + self.height//2),
                (self.x, self.y + self.height//2)
            ])

            pygame.draw.polygon(screen, GREEN, [
                (self.x + self.width, self.y + self.height//3),
                (self.x + self.width + 15, self.y + self.height//2),
                (self.x + self.width, self.y + self.height//2)
            ])

    def get_rect(self):
        return pygame.Rect(self.x, self.y, self.width, self.height)

    def update_invincible(self):
        if self.invincible:
            current_time = pygame.time.get_ticks()
            if current_time - self.invincible_timer > 2000:  # 2秒无敌时间
                self.invincible = False

# 陨石类


class Asteroid:
    def __init__(self):
        self.radius = random.randint(15, 40)
        self.x = random.randint(0, WIDTH)
        self.y = -self.radius
        self.speed = random.uniform(2.0, 5.0)
        self.color = (random.randint(100, 200), random.randint(
            100, 200), random.randint(100, 200))
        self.rotation = 0
        self.rotation_speed = random.uniform(-2.0, 2.0)

    def move(self):
        self.y += self.speed
        self.rotation += self.rotation_speed

    def draw(self):
        # 绘制陨石（带旋转的多边形）
        points = []
        for i in range(8):
            angle = math.radians(self.rotation + i * 45)
            point_x = self.x + math.cos(angle) * self.radius
            point_y = self.y + math.sin(angle) * self.radius
            points.append((point_x, point_y))

        pygame.draw.polygon(screen, self.color, points)

    def get_rect(self):
        return pygame.Rect(self.x - self.radius, self.y - self.radius,
                           self.radius * 2, self.radius * 2)

    def is_off_screen(self):
        return self.y > HEIGHT + self.radius

# 道具类


class PowerUp:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.radius = 10
        self.type = random.choice(["life", "slow", "shield"])
        self.speed = 2
        self.colors = {
            "life": RED,
            "slow": YELLOW,
            "shield": PURPLE
        }

    def move(self):
        self.y += self.speed

    def draw(self):
        color = self.colors[self.type]
        pygame.draw.circle(
            screen, color, (int(self.x), int(self.y)), self.radius)

        # 绘制图标
        if self.type == "life":
            pygame.draw.polygon(screen, WHITE, [
                (self.x, self.y - 5),
                (self.x - 4, self.y + 3),
                (self.x + 4, self.y + 3)
            ])
        elif self.type == "slow":
            pygame.draw.circle(screen, WHITE, (int(self.x), int(self.y)), 5, 1)
        elif self.type == "shield":
            pygame.draw.circle(screen, WHITE, (int(self.x), int(self.y)), 6, 2)

    def get_rect(self):
        return pygame.Rect(self.x - self.radius, self.y - self.radius,
                           self.radius * 2, self.radius * 2)

    def is_off_screen(self):
        return self.y > HEIGHT + self.radius

# 爆炸效果类


class Explosion:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.radius = 5
        self.max_radius = 30
        self.growth_rate = 2
        self.color = YELLOW

    def update(self):
        self.radius += self.growth_rate
        return self.radius <= self.max_radius

    def draw(self):
        pygame.draw.circle(screen, self.color, (int(
            self.x), int(self.y)), self.radius, 2)
        pygame.draw.circle(
            screen, RED, (int(self.x), int(self.y)), self.radius - 5, 1)

# 游戏状态


class Game:
    def __init__(self):
        self.player = Player()
        self.asteroids = []
        self.powerups = []
        self.explosions = []
        self.game_over = False
        self.paused = False
        self.asteroid_timer = 0
        self.powerup_timer = 0
        self.clock = pygame.time.Clock()
        self.font = pygame.font.SysFont(None, 36)
        self.small_font = pygame.font.SysFont(None, 24)
        self.game_speed = 1.0
        self.slow_timer = 0

    def spawn_asteroid(self):
        if random.random() < 0.05:  # 5%几率生成陨石
            self.asteroids.append(Asteroid())

    def spawn_powerup(self):
        if random.random() < 0.01:  # 1%几率生成道具
            x = random.randint(20, WIDTH - 20)
            self.powerups.append(PowerUp(x, 0))

    def check_collisions(self):
        player_rect = self.player.get_rect()

        # 检查陨石碰撞
        for asteroid in self.asteroids[:]:
            if player_rect.colliderect(asteroid.get_rect()):
                if not self.player.invincible:
                    self.player.lives -= 1
                    self.player.invincible = True
                    self.player.invincible_timer = pygame.time.get_ticks()

                    # 创建爆炸效果
                    self.explosions.append(Explosion(asteroid.x, asteroid.y))

                    # 移除被撞到的陨石
                    self.asteroids.remove(asteroid)

                    if self.player.lives <= 0:
                        self.game_over = True
                    break

        # 检查道具碰撞
        for powerup in self.powerups[:]:
            if player_rect.colliderect(powerup.get_rect()):
                if powerup.type == "life":
                    self.player.lives = min(5, self.player.lives + 1)
                elif powerup.type == "slow":
                    self.game_speed = 0.5
                    self.slow_timer = pygame.time.get_ticks()
                elif powerup.type == "shield":
                    self.player.invincible = True
                    self.player.invincible_timer = pygame.time.get_ticks()

                self.powerups.remove(powerup)

    def update(self):
        if self.paused or self.game_over:
            return

        current_time = pygame.time.get_ticks()

        # 更新游戏速度
        if self.game_speed < 1.0 and current_time - self.slow_timer > 5000:  # 5秒减速效果
            self.game_speed = 1.0

        # 玩家移动
        keys = pygame.key.get_pressed()
        self.player.move(keys)
        self.player.update_invincible()

        # 生成陨石
        self.asteroid_timer += 1
        if self.asteroid_timer > 20 / self.game_speed:
            self.spawn_asteroid()
            self.asteroid_timer = 0

        # 生成道具
        self.powerup_timer += 1
        if self.powerup_timer > 100:
            self.spawn_powerup()
            self.powerup_timer = 0

        # 更新陨石位置
        for asteroid in self.asteroids[:]:
            asteroid.move()
            if asteroid.is_off_screen():
                self.asteroids.remove(asteroid)
                self.player.score += 1

        # 更新道具位置
        for powerup in self.powerups[:]:
            powerup.move()
            if powerup.is_off_screen():
                self.powerups.remove(powerup)

        # 更新爆炸效果
        for explosion in self.explosions[:]:
            if not explosion.update():
                self.explosions.remove(explosion)

        # 检查碰撞
        self.check_collisions()

    def draw(self):
        # 绘制背景
        screen.fill(BLACK)

        # 绘制星空背景
        for _ in range(50):
            x = random.randint(0, WIDTH)
            y = random.randint(0, HEIGHT)
            size = random.randint(1, 3)
            brightness = random.randint(100, 255)
            pygame.draw.circle(
                screen, (brightness, brightness, brightness), (x, y), size)

        # 绘制游戏元素
        for asteroid in self.asteroids:
            asteroid.draw()

        for powerup in self.powerups:
            powerup.draw()

        for explosion in self.explosions:
            explosion.draw()

        self.player.draw()

        # 绘制UI
        score_text = self.font.render(f"分数: {self.player.score}", True, GREEN)
        screen.blit(score_text, (10, 10))

        lives_text = self.font.render(f"生命: {self.player.lives}", True, RED)
        screen.blit(lives_text, (10, 50))

        # 绘制控制说明
        controls = [
            "控制: ↑↓←→ 或 WASD 移动",
            "P: 暂停/继续",
            "R: 重新开始",
            "ESC: 退出游戏"
        ]

        for i, text in enumerate(controls):
            control_text = self.small_font.render(text, True, WHITE)
            screen.blit(control_text, (WIDTH - 200, 10 + i * 25))

        # 绘制道具说明
        powerup_info = [
            "道具说明:",
            "红色: 增加生命",
            "黄色: 减速陨石",
            "紫色: 无敌护盾"
        ]

        for i, text in enumerate(powerup_info):
            info_text = self.small_font.render(text, True, WHITE)
            screen.blit(info_text, (WIDTH - 200, 120 + i * 25))

        # 如果游戏暂停
        if self.paused:
            pause_surface = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)
            pause_surface.fill((0, 0, 0, 128))
            screen.blit(pause_surface, (0, 0))

            pause_text = self.font.render("游戏暂停 - 按P继续", True, YELLOW)
            screen.blit(
                pause_text, (WIDTH//2 - pause_text.get_width()//2, HEIGHT//2))

        # 如果游戏结束
        if self.game_over:
            game_over_surface = pygame.Surface(
                (WIDTH, HEIGHT), pygame.SRCALPHA)
            game_over_surface.fill((0, 0, 0, 200))
            screen.blit(game_over_surface, (0, 0))

            game_over_text = self.font.render("游戏结束!", True, RED)
            screen.blit(game_over_text, (WIDTH//2 -
                        game_over_text.get_width()//2, HEIGHT//2 - 50))

            final_score = self.font.render(
                f"最终分数: {self.player.score}", True, GREEN)
            screen.blit(final_score, (WIDTH//2 -
                        final_score.get_width()//2, HEIGHT//2))

            restart_text = self.font.render("按R重新开始，ESC退出", True, YELLOW)
            screen.blit(restart_text, (WIDTH//2 -
                        restart_text.get_width()//2, HEIGHT//2 + 50))

    def run(self):
        running = True

        while running:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running = False

                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        running = False

                    if event.key == pygame.K_p:
                        self.paused = not self.paused

                    if event.key == pygame.K_r and self.game_over:
                        # 重新开始游戏
                        self.__init__()

            # 更新游戏状态
            self.update()

            # 绘制游戏
            self.draw()

            # 更新显示
            pygame.display.flip()

            # 控制帧率
            self.clock.tick(60)

        pygame.quit()
        sys.exit()


# 运行游戏
if __name__ == "__main__":
    print("=" * 50)
    print("飞行躲避游戏 - 元宝出品")
    print("=" * 50)
    print("游戏说明:")
    print("1. 使用方向键或WASD控制飞机移动")
    print("2. 避开陨石，收集道具")
    print("3. 红色道具: 增加生命")
    print("4. 黄色道具: 减速陨石5秒")
    print("5. 紫色道具: 获得2秒无敌护盾")
    print("6. 撞到陨石会损失生命，生命为0时游戏结束")
    print("=" * 50)
    print("游戏即将开始...")

    game = Game()
    game.run()
