import pygame
import random
import sys

# 初始化 Pygame
pygame.init()

# 常量定义
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
FPS = 60

# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 50, 50)
BLUE = (50, 50, 255)
GREEN = (50, 200, 50)
YELLOW = (255, 255, 0)
PURPLE = (200, 50, 200)  # 玩家子弹颜色
CYAN = (0, 255, 255)     # 敌机子弹颜色

# 玩家设置
PLAYER_WIDTH = 50
PLAYER_HEIGHT = 30
PLAYER_SPEED = 7
PLAYER_SHOOT_COOLDOWN = 15  # 玩家射击冷却时间（帧数）

# 敌机设置
ENEMY_WIDTH = 40
ENEMY_HEIGHT = 40
ENEMY_SPEED_BASE = 3  # 降低基础速度，因为现在要躲避子弹
ENEMY_SPAWN_RATE = 60  # 每多少帧生成一个敌机
ENEMY_SHOOT_CHANCE = 0.02  # 每帧敌机发射子弹的概率
ENEMY_SHOOT_COOLDOWN = 45  # 敌机射击冷却时间（帧数）

# 子弹设置
BULLET_WIDTH = 5
BULLET_HEIGHT = 15
PLAYER_BULLET_SPEED = -10  # 向上飞
ENEMY_BULLET_SPEED = 7     # 向下飞


class Bullet:
    def __init__(self, x, y, speed, is_player_bullet=True):
        self.rect = pygame.Rect(x - BULLET_WIDTH//2, y,
                                BULLET_WIDTH, BULLET_HEIGHT)
        self.speed = speed
        self.is_player_bullet = is_player_bullet
        self.color = PURPLE if is_player_bullet else CYAN

    def update(self):
        self.rect.y += self.speed

    def draw(self, screen):
        pygame.draw.rect(screen, self.color, self.rect)
        # 子弹头部效果
        if self.is_player_bullet:
            pygame.draw.circle(
                screen, YELLOW, (self.rect.centerx, self.rect.top + 3), 3)
        else:
            pygame.draw.circle(
                screen, RED, (self.rect.centerx, self.rect.bottom - 3), 3)

    def is_off_screen(self):
        return self.rect.bottom < 0 or self.rect.top > SCREEN_HEIGHT


class Player:
    def __init__(self):
        self.width = PLAYER_WIDTH
        self.height = PLAYER_HEIGHT
        self.x = SCREEN_WIDTH // 2 - self.width // 2
        self.y = SCREEN_HEIGHT - self.height - 20
        self.speed = PLAYER_SPEED
        self.rect = pygame.Rect(self.x, self.y, self.width, self.height)
        self.bullets = []
        self.shoot_cooldown = 0
        self.lives = 3  # 玩家生命值
        self.invincible = 0  # 无敌时间（被击中后）

    def move(self, keys):
        if keys[pygame.K_LEFT] and self.rect.left > 0:
            self.rect.x -= self.speed
        if keys[pygame.K_RIGHT] and self.rect.right < SCREEN_WIDTH:
            self.rect.x += self.speed
        if keys[pygame.K_UP] and self.rect.top > 0:
            self.rect.y -= self.speed
        if keys[pygame.K_DOWN] and self.rect.bottom < SCREEN_HEIGHT:
            self.rect.y += self.speed

    def shoot(self):
        if self.shoot_cooldown <= 0:
            # 从飞机中心发射子弹
            bullet = Bullet(self.rect.centerx, self.rect.top,
                            PLAYER_BULLET_SPEED, True)
            self.bullets.append(bullet)
            self.shoot_cooldown = PLAYER_SHOOT_COOLDOWN

    def update(self):
        # 更新射击冷却
        if self.shoot_cooldown > 0:
            self.shoot_cooldown -= 1

        # 更新无敌时间
        if self.invincible > 0:
            self.invincible -= 1

        # 更新子弹
        for bullet in self.bullets[:]:
            bullet.update()
            if bullet.is_off_screen():
                self.bullets.remove(bullet)

    def draw(self, screen):
        # 绘制玩家飞机（无敌时闪烁）
        if self.invincible <= 0 or self.invincible % 6 < 3:
            pygame.draw.rect(screen, BLUE, self.rect)
            # 机翼
            pygame.draw.polygon(screen, BLUE, [
                (self.rect.centerx, self.rect.top - 10),
                (self.rect.left, self.rect.centery),
                (self.rect.right, self.rect.centery)
            ])
            # 驾驶舱
            pygame.draw.circle(
                screen, WHITE, (self.rect.centerx, self.rect.centery), 8)

        # 绘制子弹
        for bullet in self.bullets:
            bullet.draw(screen)


class Enemy:
    def __init__(self, speed_multiplier=1.0):
        self.width = ENEMY_WIDTH
        self.height = ENEMY_HEIGHT
        self.x = random.randint(0, SCREEN_WIDTH - self.width)
        self.y = -self.height
        self.speed = ENEMY_SPEED_BASE * \
            speed_multiplier + random.uniform(-1, 1)
        self.rect = pygame.Rect(self.x, self.y, self.width, self.height)
        self.color = RED
        self.bullets = []
        self.shoot_cooldown = 0
        self.health = 2  # 敌机生命值

    def update(self):
        self.rect.y += self.speed

        # 敌机射击逻辑
        if self.shoot_cooldown > 0:
            self.shoot_cooldown -= 1
        elif random.random() < ENEMY_SHOOT_CHANCE and self.rect.top > 0:
            self.shoot()

        # 更新子弹
        for bullet in self.bullets[:]:
            bullet.update()
            if bullet.is_off_screen():
                self.bullets.remove(bullet)

    def shoot(self):
        # 从敌机底部发射子弹
        bullet = Bullet(self.rect.centerx, self.rect.bottom,
                        ENEMY_BULLET_SPEED, False)
        self.bullets.append(bullet)
        self.shoot_cooldown = ENEMY_SHOOT_COOLDOWN

    def draw(self, screen):
        # 绘制敌机
        pygame.draw.rect(screen, self.color, self.rect)
        # 简单的装饰
        pygame.draw.circle(
            screen, YELLOW, (self.rect.centerx, self.rect.centery), 5)
        # 绘制生命值条
        health_width = self.width * (self.health / 2)
        pygame.draw.rect(screen, GREEN, (self.rect.left,
                         self.rect.top - 5, health_width, 3))

        # 绘制子弹
        for bullet in self.bullets:
            bullet.draw(screen)


def draw_text(screen, text, size, x, y, color=WHITE):
    font = pygame.font.SysFont(None, size)
    text_surface = font.render(text, True, color)
    text_rect = text_surface.get_rect()
    text_rect.midtop = (x, y)
    screen.blit(text_surface, text_rect)


def main():
    screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
    pygame.display.set_caption("Python 飞机大战游戏")
    clock = pygame.time.Clock()

    player = Player()
    enemies = []
    score = 0
    game_over = False
    frame_count = 0
    difficulty_multiplier = 1.0

    running = True
    while running:
        # 1. 事件处理
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE and not game_over:
                    player.shoot()
                if event.key == pygame.K_r and game_over:
                    # 重置游戏
                    main()
                    return

        if not game_over:
            # 2. 更新状态
            keys = pygame.key.get_pressed()
            player.move(keys)
            player.update()

            # 生成敌机
            frame_count += 1
            current_spawn_rate = max(20, ENEMY_SPAWN_RATE - int(score / 50))
            if frame_count % current_spawn_rate == 0:
                enemies.append(Enemy(difficulty_multiplier))

            # 更新敌机
            for enemy in enemies[:]:
                enemy.update()

                # 检测玩家子弹与敌机的碰撞
                for bullet in player.bullets[:]:
                    if enemy.rect.colliderect(bullet.rect):
                        enemy.health -= 1
                        player.bullets.remove(bullet)
                        if enemy.health <= 0:
                            enemies.remove(enemy)
                            score += 20
                            # 每100分增加难度
                            if score % 100 == 0:
                                difficulty_multiplier += 0.1
                        break

                # 检测敌机子弹与玩家的碰撞
                if player.invincible <= 0:
                    for bullet in enemy.bullets[:]:
                        if player.rect.colliderect(bullet.rect):
                            player.lives -= 1
                            player.invincible = 60  # 1秒无敌时间（60帧）
                            enemy.bullets.remove(bullet)
                            if player.lives <= 0:
                                game_over = True
                            break

                # 检测敌机与玩家的碰撞
                if player.invincible <= 0 and player.rect.colliderect(enemy.rect):
                    player.lives -= 1
                    player.invincible = 60
                    enemies.remove(enemy)
                    if player.lives <= 0:
                        game_over = True

                # 移除超出屏幕的敌机
                if enemy.rect.top > SCREEN_HEIGHT:
                    enemies.remove(enemy)

        # 3. 绘制画面
        screen.fill(BLACK)

        # 绘制星空背景
        for _ in range(15):
            x = random.randint(0, SCREEN_WIDTH)
            y = random.randint(0, SCREEN_HEIGHT)
            pygame.draw.circle(screen, WHITE, (x, y), 1)

        # 绘制所有敌机
        for enemy in enemies:
            enemy.draw(screen)

        # 绘制玩家
        player.draw(screen)

        # 显示分数和生命值
        draw_text(screen, f"Score: {score}", 30, 70, 10)
        draw_text(screen, f"Lives: {player.lives}", 30, SCREEN_WIDTH - 70, 10)

        # 显示控制提示
        draw_text(screen, "Move: Arrow Keys | Shoot: Space",
                  20, SCREEN_WIDTH // 2, 10, GREEN)

        if game_over:
            draw_text(screen, "GAME OVER", 60, SCREEN_WIDTH //
                      2, SCREEN_HEIGHT // 2 - 20, RED)
            draw_text(screen, f"Final Score: {score}", 40,
                      SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2 + 30, WHITE)
            draw_text(screen, "Press 'R' to Restart", 30,
                      SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2 + 80, GREEN)

        pygame.display.flip()
        clock.tick(FPS)

    pygame.quit()
    sys.exit()


if __name__ == "__main__":
    main()
