import pygame
import sys
import random
import os
import math  # 添加这行

# 初始化pygame
pygame.init()

# 游戏窗口设置
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("二维移动射击游戏")
clock = pygame.time.Clock()

# 颜色定义
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 50, 50)
GREEN = (50, 255, 50)
BLUE = (50, 100, 255)
YELLOW = (255, 255, 50)
PURPLE = (180, 50, 230)
ORANGE = (255, 150, 50)
CYAN = (0, 200, 255)

# 创建字体函数


def create_font(size=24):
    try:
        # 尝试创建字体
        return pygame.font.Font(None, size)
    except:
        # 如果失败，返回None
        return None

# 玩家类


class Player:
    def __init__(self):
        self.width = 40
        self.height = 40
        self.x = WIDTH // 2
        self.y = HEIGHT - 100
        self.speed = 5
        self.color = BLUE
        self.health = 100
        self.max_health = 100
        self.shoot_cooldown = 0
        self.shoot_delay = 10

    def move(self, keys):
        if keys[pygame.K_LEFT] and self.x > 0:
            self.x -= self.speed
        if keys[pygame.K_RIGHT] and self.x < WIDTH - self.width:
            self.x += self.speed
        if keys[pygame.K_UP] and self.y > 0:
            self.y -= self.speed
        if keys[pygame.K_DOWN] and self.y < HEIGHT - self.height:
            self.y += self.speed

    def shoot(self, bullets):
        if self.shoot_cooldown <= 0:
            bullets.append(Bullet(self.x + self.width //
                           2 - 3, self.y, 0, -10, GREEN))
            self.shoot_cooldown = self.shoot_delay

    def update(self):
        if self.shoot_cooldown > 0:
            self.shoot_cooldown -= 1

    def draw(self, surface):
        # 绘制玩家飞船
        pygame.draw.polygon(surface, self.color, [
            (self.x + self.width//2, self.y),  # 顶部中点
            (self.x, self.y + self.height),    # 左下角
            (self.x + self.width, self.y + self.height)  # 右下角
        ])

        # 绘制生命条
        bar_width = self.width
        bar_x = self.x
        bar_y = self.y - 10
        pygame.draw.rect(surface, RED, (bar_x, bar_y, bar_width, 5))
        pygame.draw.rect(surface, GREEN, (bar_x, bar_y,
                         bar_width * (self.health/self.max_health), 5))

    def get_rect(self):
        return pygame.Rect(self.x, self.y, self.width, self.height)

# 子弹类


class Bullet:
    def __init__(self, x, y, dx, dy, color=YELLOW):
        self.x = x
        self.y = y
        self.dx = dx
        self.dy = dy
        self.radius = 4
        self.color = color

    def update(self):
        self.x += self.dx
        self.y += self.dy

    def draw(self, surface):
        pygame.draw.circle(surface, self.color,
                           (int(self.x), int(self.y)), self.radius)

    def is_off_screen(self):
        return (self.x < 0 or self.x > WIDTH or
                self.y < 0 or self.y > HEIGHT)

    def get_rect(self):
        return pygame.Rect(self.x - self.radius, self.y - self.radius,
                           self.radius * 2, self.radius * 2)

# 敌人类


class Enemy:
    def __init__(self):
        self.width = 30
        self.height = 30
        self.x = random.randint(0, WIDTH - self.width)
        self.y = random.randint(-100, -40)
        self.speed = random.uniform(1.0, 3.0)
        self.color = RED
        self.health = 30

    def update(self):
        self.y += self.speed

    def draw(self, surface):
        pygame.draw.rect(surface, self.color,
                         (self.x, self.y, self.width, self.height))

    def is_off_screen(self):
        return self.y > HEIGHT

    def get_rect(self):
        return pygame.Rect(self.x, self.y, self.width, self.height)

# 爆炸效果类


class Explosion:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.radius = 5
        self.max_radius = 20
        self.growth_rate = 1.5
        self.color = YELLOW
        self.active = True

    def update(self):
        self.radius += self.growth_rate
        if self.radius >= self.max_radius:
            self.active = False

    def draw(self, surface):
        pygame.draw.circle(surface, self.color, (int(
            self.x), int(self.y)), int(self.radius), 2)
        pygame.draw.circle(surface, ORANGE, (int(self.x),
                           int(self.y)), int(self.radius/2), 1)

# 游戏主函数


def main():
    player = Player()
    bullets = []
    enemies = []
    explosions = []

    # 游戏状态
    score = 0
    enemy_spawn_timer = 0
    enemy_spawn_delay = 60

    # 创建字体
    font_small = create_font(20)
    font_normal = create_font(24)
    font_large = create_font(36)

    running = True
    while running:
        # 处理事件
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    player.shoot(bullets)
                elif event.key == pygame.K_ESCAPE:
                    running = False
                elif event.key == pygame.K_r and player.health <= 0:
                    # 重新开始游戏
                    player = Player()
                    bullets = []
                    enemies = []
                    explosions = []
                    score = 0
                    enemy_spawn_timer = 0

        # 获取按键状态
        keys = pygame.key.get_pressed()

        # 玩家移动
        player.move(keys)

        # 自动射击
        if keys[pygame.K_SPACE]:
            player.shoot(bullets)

        # 更新玩家
        player.update()

        # 生成敌人
        enemy_spawn_timer += 1
        if enemy_spawn_timer >= enemy_spawn_delay:
            enemies.append(Enemy())
            enemy_spawn_timer = 0

        # 更新子弹
        for bullet in bullets[:]:
            bullet.update()
            if bullet.is_off_screen():
                bullets.remove(bullet)

        # 更新敌人
        for enemy in enemies[:]:
            enemy.update()

            if enemy.is_off_screen():
                enemies.remove(enemy)

        # 更新爆炸效果
        for explosion in explosions[:]:
            explosion.update()
            if not explosion.active:
                explosions.remove(explosion)

        # 碰撞检测：子弹 vs 敌人
        for bullet in bullets[:]:
            for enemy in enemies[:]:
                if bullet.get_rect().colliderect(enemy.get_rect()):
                    explosions.append(
                        Explosion(enemy.x + enemy.width//2, enemy.y + enemy.height//2))
                    if bullet in bullets:
                        bullets.remove(bullet)
                    if enemy in enemies:
                        enemies.remove(enemy)
                    score += 10
                    break

        # 碰撞检测：敌人 vs 玩家
        for enemy in enemies[:]:
            if enemy.get_rect().colliderect(player.get_rect()):
                explosions.append(
                    Explosion(enemy.x + enemy.width//2, enemy.y + enemy.height//2))
                if enemy in enemies:
                    enemies.remove(enemy)
                player.health -= 20

        # 绘制
        screen.fill(BLACK)

        # 绘制网格背景
        for x in range(0, WIDTH, 40):
            pygame.draw.line(screen, (20, 20, 30), (x, 0), (x, HEIGHT), 1)
        for y in range(0, HEIGHT, 40):
            pygame.draw.line(screen, (20, 20, 30), (0, y), (WIDTH, y), 1)

        # 绘制所有对象
        player.draw(screen)

        for bullet in bullets:
            bullet.draw(screen)

        for enemy in enemies:
            enemy.draw(screen)

        for explosion in explosions:
            explosion.draw(screen)

        # 绘制UI
        if font_normal:
            score_text = font_normal.render(f"Score: {score}", True, WHITE)
            health_text = font_normal.render(
                f"Health: {player.health}", True, GREEN)
            screen.blit(score_text, (10, 10))
            screen.blit(health_text, (10, 50))

            # 控制说明
            controls = [
                "Arrow Keys: Move",
                "Space: Shoot",
                "R: Restart",
                "ESC: Quit"
            ]

            for i, text in enumerate(controls):
                if font_small:
                    control_text = font_small.render(text, True, WHITE)
                    screen.blit(
                        control_text, (WIDTH - control_text.get_width() - 10, 10 + i * 25))
        else:
            # 如果字体创建失败，使用简单图形表示
            pygame.draw.rect(screen, WHITE, (10, 10, 100, 20))
            pygame.draw.rect(screen, GREEN, (10, 40, player.health, 20))

        # 显示敌人数量
        if font_small:
            enemy_text = font_small.render(
                f"Enemies: {len(enemies)}", True, WHITE)
            screen.blit(
                enemy_text, (WIDTH - enemy_text.get_width() - 10, HEIGHT - 40))

        # 游戏结束画面
        if player.health <= 0:
            # 半透明覆盖层
            overlay = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)
            overlay.fill((0, 0, 0, 180))
            screen.blit(overlay, (0, 0))

            if font_large:
                game_over_text = font_large.render("GAME OVER", True, RED)
                final_score = font_normal.render(
                    f"Final Score: {score}", True, YELLOW)
                restart_text = font_normal.render(
                    "Press R to Restart", True, GREEN)

                screen.blit(game_over_text, (WIDTH//2 -
                            game_over_text.get_width()//2, HEIGHT//2 - 50))
                screen.blit(final_score, (WIDTH//2 -
                            final_score.get_width()//2, HEIGHT//2))
                screen.blit(restart_text, (WIDTH//2 -
                            restart_text.get_width()//2, HEIGHT//2 + 50))
            else:
                # 简单图形表示
                pygame.draw.rect(
                    screen, RED, (WIDTH//2 - 100, HEIGHT//2 - 50, 200, 50))

        pygame.display.flip()
        clock.tick(60)

    pygame.quit()
    sys.exit()


if __name__ == "__main__":
    main()
