import pygame
import random
import math

# 初始化pygame
pygame.init()

# 窗口设置
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("2D移动射击小游戏")

# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)

# 帧率控制
clock = pygame.time.Clock()
FPS = 60

# ---------------------- 玩家类 ----------------------
class Player:
    def __init__(self):
        self.x = WIDTH // 2
        self.y = HEIGHT // 2
        self.radius = 20
        self.speed = 5
        self.hp = 100

    def update(self, keys):
        # WASD移动
        if keys[pygame.K_w]:
            if self.y - self.radius > 0:
                self.y -= self.speed
        if keys[pygame.K_s]:
            if self.y + self.radius < HEIGHT:
                self.y += self.speed
        if keys[pygame.K_a]:
            if self.x - self.radius > 0:
                self.x -= self.speed
        if keys[pygame.K_d]:
            if self.x + self.radius < WIDTH:
                self.x += self.speed

    def draw(self):
        pygame.draw.circle(screen, BLUE, (int(self.x), int(self.y)), self.radius)

# ---------------------- 子弹类 ----------------------
class Bullet:
    def __init__(self, x, y, target_x, target_y):
        self.x = x
        self.y = y
        self.radius = 6
        self.speed = 10
        angle = math.atan2(target_y - y, target_x - x)
        self.vx = math.cos(angle) * self.speed
        self.vy = math.sin(angle) * self.speed

    def update(self):
        self.x += self.vx
        self.y += self.vy

    def off_screen(self):
        return self.x < 0 or self.x > WIDTH or self.y < 0 or self.y > HEIGHT

    def draw(self):
        pygame.draw.circle(screen, WHITE, (int(self.x), int(self.y)), self.radius)

# ---------------------- 敌人类 ----------------------
class Enemy:
    def __init__(self, speed_modifier):
        self.radius = 16
        # 根据难度倍率调整敌人速度
        base_min = 1.2 + speed_modifier
        base_max = 2.5 + speed_modifier
        self.speed = random.uniform(base_min, base_max)
        side = random.randint(0, 3)
        if side == 0:
            self.x = random.randint(0, WIDTH)
            self.y = -self.radius
        elif side == 1:
            self.x = random.randint(0, WIDTH)
            self.y = HEIGHT + self.radius
        elif side == 2:
            self.x = -self.radius
            self.y = random.randint(0, HEIGHT)
        else:
            self.x = WIDTH + self.radius
            self.y = random.randint(0, HEIGHT)

    def update(self, player):
        angle = math.atan2(player.y - self.y, player.x - self.x)
        self.x += math.cos(angle) * self.speed
        self.y += math.sin(angle) * self.speed

    def draw(self):
        pygame.draw.circle(screen, RED, (int(self.x), int(self.y)), self.radius)

# 碰撞检测
def check_collision(obj1, obj2, r1, r2):
    dx = obj1.x - obj2.x
    dy = obj1.y - obj2.y
    dist = math.hypot(dx, dy)
    return dist < r1 + r2

# ========== 游戏主程序 ==========
def main():
    player = Player()
    bullets = []
    enemies = []
    spawn_timer = 0
    score = 0
    font = pygame.font.Font(None, 36)

    running = True
    while running:
        clock.tick(FPS)
        screen.fill(BLACK)
        mouse_x, mouse_y = pygame.mouse.get_pos()

        # 事件处理
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            # 鼠标点击发射子弹
            if event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1:
                    bullets.append(Bullet(player.x, player.y, mouse_x, mouse_y))

        keys = pygame.key.get_pressed()
        player.update(keys)

        # =====难度控制：分数越高，敌人越快、刷新越快=====
        difficulty = score / 200  # 速度增量
        difficulty = min(difficulty, 3.0)  # 最大速度增幅，防止过于离谱
        spawn_interval = max(30, 80 - int(score / 30)) # 刷新间隔不断缩短

        # 生成敌人
        spawn_timer += 1
        if spawn_timer > spawn_interval:
            enemies.append(Enemy(difficulty))
            spawn_timer = 0

        # 更新子弹
        new_bullets = []
        for b in bullets:
            b.update()
            if not b.off_screen():
                new_bullets.append(b)
        bullets = new_bullets

        # 更新敌人
        for e in enemies:
            e.update(player)

        # 子弹击中敌人
        survive_enemies = []
        for enemy in enemies:
            hit = False
            for bullet in bullets:
                if check_collision(bullet, enemy, bullet.radius, enemy.radius):
                    hit = True
                    score += 10
                    bullets.remove(bullet)
                    break
            if not hit:
                survive_enemies.append(enemy)
        enemies = survive_enemies

        # 敌人撞到玩家
        final_enemy = []
        for enemy in enemies:
            if check_collision(player, enemy, player.radius, enemy.radius):
                player.hp -= 20
            else:
                final_enemy.append(enemy)
        enemies = final_enemy

        # 游戏结束判断
        if player.hp <= 0:
            over_text = font.render(f"游戏结束！得分：{score}", True, WHITE)
            screen.blit(over_text, (WIDTH//2 - 120, HEIGHT//2))
            pygame.display.flip()
            pygame.time.wait(2000)
            running = False

        # 绘制
        player.draw()
        for b in bullets:
            b.draw()
        for e in enemies:
            e.draw()

        # UI文字
        hp_text = font.render(f"血量: {player.hp}", True, GREEN)
        score_text = font.render(f"分数: {score}", True, WHITE)
        diff_text = font.render(f"难度倍率: {difficulty:.1f}", True, YELLOW)
        screen.blit(hp_text, (10, 10))
        screen.blit(score_text, (10, 45))
        screen.blit(diff_text, (10, 80))

        pygame.display.update()

    pygame.quit()

if __name__ == "__main__":
    main()
