import pygame
import sys
import random
import math

# 初始化
pygame.init()

# 屏幕设置
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("练枪模拟器 - Aim Trainer")

# 颜色
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 50, 50)
BLUE = (50, 100, 255)
YELLOW = (255, 255, 0)
GREEN = (50, 255, 50)
GRAY = (100, 100, 100)

# 时钟
clock = pygame.time.Clock()
FPS = 60

# 字体
font_small = pygame.font.Font(None, 36)
font_big = pygame.font.Font(None, 72)

class Target:
    """靶子类，可出现在随机位置并可移动"""
    def __init__(self):
        self.radius = random.randint(20, 50)          # 随机大小
        self.x = random.randint(self.radius, WIDTH - self.radius)
        self.y = random.randint(self.radius, HEIGHT - self.radius)
        # 移动参数
        self.speed_x = random.uniform(-3, 3)
        self.speed_y = random.uniform(-3, 3)
        self.color = RED
        self.alive = True

    def update(self):
        """移动并碰到边界反弹"""
        self.x += self.speed_x
        self.y += self.speed_y
        # 边界反弹
        if self.x - self.radius <= 0 or self.x + self.radius >= WIDTH:
            self.speed_x *= -1
            self.x = max(self.radius, min(self.x, WIDTH - self.radius))
        if self.y - self.radius <= 0 or self.y + self.radius >= HEIGHT:
            self.speed_y *= -1
            self.y = max(self.radius, min(self.y, HEIGHT - self.radius))

    def draw(self, surface):
        """绘制靶子（同心圆 + 十字准星感）"""
        # 外圈
        pygame.draw.circle(surface, RED, (self.x, self.y), self.radius)
        pygame.draw.circle(surface, WHITE, (self.x, self.y), self.radius // 2)
        pygame.draw.circle(surface, RED, (self.x, self.y), self.radius // 4)
        # 十字线
        pygame.draw.line(surface, BLACK, (self.x - self.radius, self.y), (self.x + self.radius, self.y), 2)
        pygame.draw.line(surface, BLACK, (self.x, self.y - self.radius), (self.x, self.y + self.radius), 2)

    def is_hit(self, pos):
        """检测点是否在靶内"""
        dx = pos[0] - self.x
        dy = pos[1] - self.y
        return math.hypot(dx, dy) <= self.radius

    def get_score(self, pos):
        """根据命中位置距离圆心的距离给分（越近越高）"""
        dx = pos[0] - self.x
        dy = pos[1] - self.y
        dist = math.hypot(dx, dy)
        if dist <= self.radius // 4:
            return 100       # 精确命中
        elif dist <= self.radius // 2:
            return 50
        else:
            return 25

class AimTrainer:
    def __init__(self):
        self.reset()

    def reset(self):
        """重置游戏状态"""
        self.targets = [Target() for _ in range(3)]   # 同时存在3个靶子
        self.score = 0
        self.shots = 0
        self.hits = 0
        self.time_left = 30.0          # 倒计时30秒
        self.game_over = False
        self.start_ticks = pygame.time.get_ticks()

    def run(self):
        """主循环"""
        while True:
            dt = clock.tick(FPS) / 1000.0   # 帧间隔（秒）

            # ---- 事件处理 ----
            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_SPACE and self.game_over:
                        self.reset()        # 游戏结束时按空格重开
                if event.type == pygame.MOUSEBUTTONDOWN and not self.game_over:
                    if event.button == 1:   # 左键射击
                        self.shots += 1
                        pos = pygame.mouse.get_pos()
                        hit_any = False
                        # 遍历靶子，优先击中面积最小的（最上层绘制最后一个）
                        for target in sorted(self.targets, key=lambda t: t.radius, reverse=True):
                            if target.is_hit(pos):
                                self.score += target.get_score(pos)
                                self.hits += 1
                                hit_any = True
                                # 替换被击中的靶子
                                self.targets.remove(target)
                                self.targets.append(Target())
                                break
                        if not hit_any:
                            # 未击中：可以播放音效或显示文字
                            pass

            # ---- 更新 ----
            if not self.game_over:
                # 更新时间
                elapsed = (pygame.time.get_ticks() - self.start_ticks) / 1000.0
                self.time_left = max(0, 30.0 - elapsed)
                if self.time_left <= 0:
                    self.game_over = True

                # 更新所有靶子
                for target in self.targets:
                    target.update()

            # ---- 绘制 ----
            screen.fill(BLACK)

            # 绘制准星（鼠标位置）
            mx, my = pygame.mouse.get_pos()
            pygame.draw.line(screen, RED, (mx - 15, my), (mx + 15, my), 2)
            pygame.draw.line(screen, RED, (mx, my - 15), (mx, my + 15), 2)
            pygame.draw.circle(screen, RED, (mx, my), 5, 1)

            # 绘制靶子
            for target in self.targets:
                target.draw(screen)

            # 显示UI
            # 分数
            score_text = font_small.render(f"得分: {self.score}", True, WHITE)
            screen.blit(score_text, (10, 10))
            # 命中率
            if self.shots > 0:
                acc = self.hits / self.shots * 100
                acc_text = font_small.render(f"命中率: {acc:.1f}%", True, WHITE)
            else:
                acc_text = font_small.render("命中率: --%", True, WHITE)
            screen.blit(acc_text, (10, 50))
            # 射击次数
            shots_text = font_small.render(f"射击: {self.shots}", True, WHITE)
            screen.blit(shots_text, (10, 90))
            # 时间
            time_color = RED if self.time_left <= 5 else WHITE
            time_text = font_small.render(f"时间: {self.time_left:.1f}s", True, time_color)
            screen.blit(time_text, (WIDTH - 200, 10))

            # 游戏结束画面
            if self.game_over:
                overlay = pygame.Surface((WIDTH, HEIGHT))
                overlay.set_alpha(180)
                overlay.fill(BLACK)
                screen.blit(overlay, (0, 0))
                game_over_text = font_big.render("训练结束", True, RED)
                screen.blit(game_over_text, (WIDTH//2 - game_over_text.get_width()//2, HEIGHT//2 - 100))
                final_score = font_small.render(f"最终得分: {self.score}  命中率: {acc:.1f}%", True, WHITE)
                screen.blit(final_score, (WIDTH//2 - final_score.get_width()//2, HEIGHT//2 - 30))
                restart_text = font_small.render("按 空格键 重新开始", True, YELLOW)
                screen.blit(restart_text, (WIDTH//2 - restart_text.get_width()//2, HEIGHT//2 + 50))

            pygame.display.flip()

# 启动
if __name__ == "__main__":
    game = AimTrainer()
    game.run()