import pygame
import sys
import random
import time
import math
from pygame.locals import *

# 初始化pygame
pygame.init()
pygame.mixer.init()

# 屏幕尺寸
SCREEN_WIDTH = 1000
SCREEN_HEIGHT = 700
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("鼠标点击训练 - 目标练习")

# 颜色定义
BACKGROUND = (25, 25, 40)
TARGET_COLORS = [
    (255, 50, 50),    # 红色
    (50, 150, 255),   # 蓝色
    (50, 255, 100),   # 绿色
    (255, 215, 0),    # 金色
    (200, 100, 255),  # 紫色
    (255, 150, 50),   # 橙色
    (100, 255, 200),  # 青色
    (255, 100, 200)   # 粉色
]
TEXT_COLOR = (255, 255, 255)
TEXT_SHADOW = (50, 50, 50)
UI_BG = (40, 40, 60, 200)
SUCCESS_COLOR = (100, 255, 100)
FAIL_COLOR = (255, 100, 100)
HIGHLIGHT_COLOR = (255, 255, 200)
GRID_COLOR = (60, 60, 80, 100)
PARTICLE_COLORS = [
    (255, 100, 100),  # 红色
    (100, 200, 255),  # 蓝色
    (100, 255, 150),  # 绿色
    (255, 220, 100)   # 黄色
]

# 游戏参数
FPS = 120
GAME_DURATION = 60  # 游戏时长（秒）
TARGET_MIN_SIZE = 20
TARGET_MAX_SIZE = 60
TARGET_SPAWN_INTERVAL = 0.5  # 生成间隔（秒）
TARGET_LIFETIME = 3.0  # 目标存在时间（秒）
TARGET_MIN_SPEED = 0.5
TARGET_MAX_SPEED = 3.0
MAX_TARGETS = 15
INITIAL_TARGET_COUNT = 5
DIFFICULTY_LEVELS = ["简单", "中等", "困难", "专家", "大师"]
DIFFICULTY_SETTINGS = {
    "简单": {"speed": 0.5, "size": 50, "lifetime": 4.0, "spawn_interval": 1.0},
    "中等": {"speed": 1.0, "size": 40, "lifetime": 3.0, "spawn_interval": 0.8},
    "困难": {"speed": 1.5, "size": 30, "lifetime": 2.5, "spawn_interval": 0.6},
    "专家": {"speed": 2.0, "size": 25, "lifetime": 2.0, "spawn_interval": 0.4},
    "大师": {"speed": 2.5, "size": 20, "lifetime": 1.5, "spawn_interval": 0.3}
}

# 游戏状态
STATE_MENU = 0
STATE_COUNTDOWN = 1
STATE_PLAYING = 2
STATE_GAME_OVER = 3
STATE_RESULTS = 4

class Target:
    def __init__(self, x, y, size, color, speed, lifetime, is_moving=False, is_bouncing=False):
        self.x = x
        self.y = y
        self.size = size
        self.color = color
        self.original_color = color
        self.speed = speed
        self.lifetime = lifetime
        self.max_lifetime = lifetime
        self.is_active = True
        self.is_moving = is_moving
        self.is_bouncing = is_bouncing
        self.move_angle = random.random() * 2 * math.pi
        self.vx = math.cos(self.move_angle) * speed
        self.vy = math.sin(self.move_angle) * speed
        self.pulse_animation = random.random() * 2 * math.pi
        self.pulse_speed = random.uniform(0.05, 0.1)
        self.pulse_amount = random.uniform(0.1, 0.2)
        self.rotation = 0
        self.rotation_speed = random.uniform(-2, 2)
        self.is_flashing = False
        self.flash_timer = 0
        self.was_hit = False
        self.particles = []
        
    def update(self, dt):
        # 更新生命周期
        self.lifetime -= dt
        if self.lifetime <= 0:
            self.is_active = False
            return False
            
        # 更新脉冲动画
        self.pulse_animation += self.pulse_speed
        
        # 更新旋转
        self.rotation += self.rotation_speed
        
        # 更新闪光效果
        if self.is_flashing:
            self.flash_timer -= dt
            if self.flash_timer <= 0:
                self.is_flashing = False
                self.color = self.original_color
                
        # 更新时间警告
        if self.lifetime < 1.0:
            # 最后1秒开始闪烁
            flash_rate = 10
            if int(self.lifetime * flash_rate) % 2 == 0:
                self.color = (255, 255, 255)
            else:
                self.color = self.original_color
        
        # 移动目标
        if self.is_moving:
            self.x += self.vx
            self.y += self.vy
            
            # 边界反弹
            if self.is_bouncing:
                if self.x - self.size < 0 or self.x + self.size > SCREEN_WIDTH:
                    self.vx = -self.vx
                if self.y - self.size < 0 or self.y + self.size > SCREEN_HEIGHT:
                    self.vy = -self.vy
            else:
                # 屏幕边界环绕
                if self.x < -self.size:
                    self.x = SCREEN_WIDTH + self.size
                elif self.x > SCREEN_WIDTH + self.size:
                    self.x = -self.size
                if self.y < -self.size:
                    self.y = SCREEN_HEIGHT + self.size
                elif self.y > SCREEN_HEIGHT + self.size:
                    self.y = -self.size
        
        # 更新粒子
        for particle in self.particles[:]:
            particle[0] += particle[2]
            particle[1] += particle[3]
            particle[4] -= 1
            particle[3] += 0.1  # 重力
            
            if particle[4] <= 0:
                self.particles.remove(particle)
                
        return True
    
    def draw(self, screen):
        if not self.is_active:
            return
            
        # 计算当前大小（包含脉冲效果）
        pulse_size = self.size * (1 + math.sin(self.pulse_animation) * self.pulse_amount)
        
        # 绘制目标阴影
        shadow_offset = 5
        shadow_alpha = 100
        shadow_surface = pygame.Surface((int(pulse_size*2 + shadow_offset*2), 
                                       int(pulse_size*2 + shadow_offset*2)), pygame.SRCALPHA)
        pygame.draw.circle(shadow_surface, (0, 0, 0, shadow_alpha), 
                          (int(pulse_size + shadow_offset), int(pulse_size + shadow_offset)), 
                          int(pulse_size))
        screen.blit(shadow_surface, (self.x - pulse_size - shadow_offset, 
                                    self.y - pulse_size - shadow_offset))
        
        # 创建目标表面
        target_surface = pygame.Surface((int(pulse_size*2), int(pulse_size*2)), pygame.SRCALPHA)
        
        # 绘制外圈
        pygame.draw.circle(target_surface, self.color, 
                          (int(pulse_size), int(pulse_size)), int(pulse_size))
        
        # 绘制内圈
        inner_color = (min(255, self.color[0] + 50), 
                      min(255, self.color[1] + 50), 
                      min(255, self.color[2] + 50))
        inner_size = pulse_size * 0.7
        pygame.draw.circle(target_surface, inner_color, 
                          (int(pulse_size), int(pulse_size)), int(inner_size))
        
        # 绘制中心
        center_color = (min(255, self.color[0] + 100), 
                       min(255, self.color[1] + 100), 
                       min(255, self.color[2] + 100))
        center_size = pulse_size * 0.3
        pygame.draw.circle(target_surface, center_color, 
                          (int(pulse_size), int(pulse_size)), int(center_size))
        
        # 绘制十字准星
        cross_length = pulse_size * 0.8
        cross_width = 3
        # 水平线
        pygame.draw.rect(target_surface, (255, 255, 255), 
                        (pulse_size - cross_length//2, pulse_size - cross_width//2, 
                         cross_length, cross_width))
        # 垂直线
        pygame.draw.rect(target_surface, (255, 255, 255), 
                        (pulse_size - cross_width//2, pulse_size - cross_length//2, 
                         cross_width, cross_length))
        
        # 旋转并绘制目标
        rotated_target = pygame.transform.rotate(target_surface, self.rotation)
        rotated_rect = rotated_target.get_rect(center=(self.x, self.y))
        screen.blit(rotated_target, rotated_rect.topleft)
        
        # 绘制粒子
        for particle in self.particles:
            px, py, vx, vy, lifetime, color = particle
            radius = max(1, lifetime // 5)
            pygame.draw.circle(screen, color, (int(px), int(py)), radius)
        
        # 绘制剩余时间条
        if self.lifetime < self.max_lifetime:
            bar_width = pulse_size * 2
            bar_height = 6
            bar_x = self.x - pulse_size
            bar_y = self.y + pulse_size + 10
            
            # 背景条
            pygame.draw.rect(screen, (100, 100, 100), 
                           (bar_x, bar_y, bar_width, bar_height))
            
            # 填充条
            fill_width = int(bar_width * (self.lifetime / self.max_lifetime))
            time_color = (255, 200, 100) if self.lifetime > 1.0 else (255, 100, 100)
            pygame.draw.rect(screen, time_color, 
                           (bar_x, bar_y, fill_width, bar_height))
    
    def is_clicked(self, mouse_x, mouse_y):
        """检查是否被点击"""
        distance = math.sqrt((mouse_x - self.x)**2 + (mouse_y - self.y)**2)
        return distance <= self.size
    
    def hit(self):
        """目标被击中"""
        self.was_hit = True
        self.is_active = False
        
        # 创建击中粒子效果
        for _ in range(20):
            angle = random.random() * 2 * math.pi
            speed = random.uniform(2, 8)
            vx = math.cos(angle) * speed
            vy = math.sin(angle) * speed
            lifetime = random.randint(20, 40)
            color = random.choice(PARTICLE_COLORS)
            
            self.particles.append([self.x, self.y, vx, vy, lifetime, color])
        
        return self.size  # 返回大小作为分数基础

class ReactionTest:
    def __init__(self):
        self.target_x = SCREEN_WIDTH // 2
        self.target_y = SCREEN_HEIGHT // 2
        self.target_size = 50
        self.target_color = (255, 50, 50)
        self.is_visible = False
        self.waiting_for_click = False
        self.start_time = 0
        self.reaction_time = 0
        self.test_count = 0
        self.results = []
        self.state = "idle"  # idle, waiting, showing, reacting
        
    def start_test(self):
        """开始新的反应测试"""
        self.state = "waiting"
        self.is_visible = False
        self.waiting_for_click = False
        
        # 随机等待时间
        wait_time = random.uniform(1.0, 3.0)
        pygame.time.set_timer(pygame.USEREVENT, int(wait_time * 1000))
        
    def show_target(self):
        """显示目标"""
        self.state = "showing"
        self.is_visible = True
        self.waiting_for_click = True
        self.start_time = time.time()
        
        # 随机位置
        margin = self.target_size + 50
        self.target_x = random.randint(margin, SCREEN_WIDTH - margin)
        self.target_y = random.randint(margin, SCREEN_HEIGHT - margin)
        
        # 随机颜色
        self.target_color = random.choice(TARGET_COLORS)
        
    def record_reaction(self):
        """记录反应时间"""
        if self.waiting_for_click:
            self.state = "reacting"
            self.reaction_time = (time.time() - self.start_time) * 1000  # 转换为毫秒
            self.results.append(self.reaction_time)
            self.test_count += 1
            self.waiting_for_click = False
            self.is_visible = False
            return self.reaction_time
        return 0
    
    def draw(self, screen):
        """绘制反应测试"""
        if self.is_visible:
            # 绘制目标
            pygame.draw.circle(screen, self.target_color, 
                             (self.target_x, self.target_y), self.target_size)
            
            # 绘制中心点
            pygame.draw.circle(screen, (255, 255, 255), 
                             (self.target_x, self.target_y), self.target_size // 3)
            
            # 绘制"点击"文字
            font = pygame.font.Font(None, 30)
            text = font.render("点击!", True, (255, 255, 255))
            text_rect = text.get_rect(center=(self.target_x, self.target_y))
            
            # 文字背景
            text_bg = pygame.Rect(text_rect.x - 10, text_rect.y - 5, 
                                text_rect.width + 20, text_rect.height + 10)
            pygame.draw.rect(screen, (0, 0, 0, 150), text_bg, border_radius=5)
            
            screen.blit(text, text_rect)
        
        # 绘制状态信息
        if self.state == "waiting":
            font = pygame.font.Font(None, 40)
            text = font.render("准备...", True, (255, 200, 100))
            screen.blit(text, (SCREEN_WIDTH//2 - text.get_width()//2, SCREEN_HEIGHT//2 - 100))
        
        # 绘制结果
        if self.results:
            self.draw_results(screen)
    
    def draw_results(self, screen):
        """绘制测试结果"""
        y_pos = 150
        font = pygame.font.Font(None, 28)
        
        # 最新结果
        latest = self.results[-1]
        color = (100, 255, 100) if latest < 300 else (255, 200, 100) if latest < 500 else (255, 100, 100)
        
        result_text = font.render(f"反应时间: {latest:.0f} ms", True, color)
        screen.blit(result_text, (SCREEN_WIDTH//2 - result_text.get_width()//2, y_pos))
        
        # 平均结果
        if len(self.results) > 1:
            avg = sum(self.results) / len(self.results)
            avg_text = font.render(f"平均: {avg:.0f} ms", True, (200, 200, 255))
            screen.blit(avg_text, (SCREEN_WIDTH//2 - avg_text.get_width()//2, y_pos + 40))
            
            # 最佳结果
            best = min(self.results)
            best_text = font.render(f"最佳: {best:.0f} ms", True, (255, 255, 100))
            screen.blit(best_text, (SCREEN_WIDTH//2 - best_text.get_width()//2, y_pos + 80))
            
            # 测试次数
            count_text = font.render(f"测试次数: {len(self.results)}", True, (200, 200, 200))
            screen.blit(count_text, (SCREEN_WIDTH//2 - count_text.get_width()//2, y_pos + 120))

class Game:
    def __init__(self):
        # 游戏状态
        self.state = STATE_MENU
        self.score = 0
        self.high_score = 0
        self.time_left = GAME_DURATION
        self.targets_hit = 0
        self.targets_missed = 0
        self.accuracy = 100.0
        self.combo = 0
        self.max_combo = 0
        self.reaction_times = []
        self.average_reaction_time = 0
        
        # 游戏设置
        self.difficulty = "中等"
        self.game_mode = "timed"  # timed, endless, reaction_test
        self.show_grid = True
        self.show_traces = True
        self.sound_effects = True
        
        # 游戏对象
        self.targets = []
        self.particles = []
        self.reaction_test = ReactionTest()
        self.mouse_trail = []
        
        # 计时器
        self.last_spawn_time = 0
        self.game_start_time = 0
        self.countdown = 3
        
        # 字体
        self.font_large = pygame.font.Font(None, 72)
        self.font_medium = pygame.font.Font(None, 48)
        self.font_small = pygame.font.Font(None, 32)
        self.font_tiny = pygame.font.Font(None, 24)
        
        # 生成初始目标
        self.generate_initial_targets()
        
        # 加载声音
        self.load_sounds()
    
    def load_sounds(self):
        """加载声音效果"""
        try:
            self.sounds = {
                'click': pygame.mixer.Sound(pygame.mixer.Sound(buffer=bytes([0])*1000)),  # 占位符
                'hit': pygame.mixer.Sound(pygame.mixer.Sound(buffer=bytes([0])*1000)),
                'miss': pygame.mixer.Sound(pygame.mixer.Sound(buffer=bytes([0])*1000)),
                'combo': pygame.mixer.Sound(pygame.mixer.Sound(buffer=bytes([0])*1000))
            }
        except:
            self.sounds = {}
            self.sound_effects = False
    
    def generate_initial_targets(self):
        """生成初始目标"""
        self.targets = []
        settings = DIFFICULTY_SETTINGS[self.difficulty]
        
        for _ in range(INITIAL_TARGET_COUNT):
            x = random.randint(TARGET_MAX_SIZE, SCREEN_WIDTH - TARGET_MAX_SIZE)
            y = random.randint(TARGET_MAX_SIZE, SCREEN_HEIGHT - TARGET_MAX_SIZE)
            size = random.randint(int(settings['size'] * 0.8), int(settings['size'] * 1.2))
            color = random.choice(TARGET_COLORS)
            speed = random.uniform(settings['speed'] * 0.5, settings['speed'] * 1.5)
            lifetime = random.uniform(settings['lifetime'] * 0.8, settings['lifetime'] * 1.2)
            is_moving = random.random() < 0.3
            is_bouncing = random.random() < 0.5
            
            target = Target(x, y, size, color, speed, lifetime, is_moving, is_bouncing)
            self.targets.append(target)
    
    def spawn_target(self):
        """生成新目标"""
        if len(self.targets) >= MAX_TARGETS:
            return
        
        settings = DIFFICULTY_SETTINGS[self.difficulty]
        
        # 随机位置
        margin = TARGET_MAX_SIZE + 20
        x = random.randint(margin, SCREEN_WIDTH - margin)
        y = random.randint(margin, SCREEN_HEIGHT - margin)
        
        # 随机大小
        size = random.randint(int(settings['size'] * 0.5), int(settings['size'] * 1.5))
        
        # 随机颜色
        color = random.choice(TARGET_COLORS)
        
        # 随机速度
        speed = random.uniform(settings['speed'] * 0.5, settings['speed'] * 1.5)
        
        # 随机存在时间
        lifetime = random.uniform(settings['lifetime'] * 0.5, settings['lifetime'] * 1.5)
        
        # 随机移动类型
        move_type = random.random()
        is_moving = move_type < 0.5
        is_bouncing = move_type < 0.3
        
        # 特殊目标概率
        if random.random() < 0.1:  # 10% 特殊目标
            # 迷你目标
            if random.random() < 0.5:
                size = int(size * 0.5)
                color = (255, 255, 100)  # 黄色
            # 快速目标
            else:
                speed *= 2
                color = (255, 100, 255)  # 粉色
        
        target = Target(x, y, size, color, speed, lifetime, is_moving, is_bouncing)
        self.targets.append(target)
    
    def update(self, dt):
        """更新游戏状态"""
        if self.state == STATE_COUNTDOWN:
            # 倒计时
            self.countdown -= dt
            if self.countdown <= 0:
                self.state = STATE_PLAYING
                self.game_start_time = time.time()
        
        elif self.state == STATE_PLAYING:
            if self.game_mode == "timed":
                # 更新时间
                elapsed = time.time() - self.game_start_time
                self.time_left = max(0, GAME_DURATION - elapsed)
                
                if self.time_left <= 0:
                    self.state = STATE_GAME_OVER
                    self.calculate_final_stats()
            
            elif self.game_mode == "reaction_test":
                # 反应测试模式
                if not self.reaction_test.waiting_for_click:
                    self.reaction_test.start_test()
            
            # 更新目标
            for target in self.targets[:]:
                if not target.update(dt):
                    if not target.was_hit:
                        self.targets_missed += 1
                        self.combo = 0
                    self.targets.remove(target)
            
            # 生成新目标
            if self.game_mode != "reaction_test":
                current_time = time.time()
                settings = DIFFICULTY_SETTINGS[self.difficulty]
                
                if current_time - self.last_spawn_time > settings['spawn_interval']:
                    self.spawn_target()
                    self.last_spawn_time = current_time
            
            # 更新粒子
            for particle in self.particles[:]:
                particle[0] += particle[2]
                particle[1] += particle[3]
                particle[4] -= 1
                particle[3] += 0.1
                
                if particle[4] <= 0:
                    self.particles.remove(particle)
            
            # 更新鼠标轨迹
            if self.show_traces:
                mouse_x, mouse_y = pygame.mouse.get_pos()
                self.mouse_trail.append((mouse_x, mouse_y, 20))  # 20帧生命周期
                
                for i, (x, y, life) in enumerate(self.mouse_trail):
                    self.mouse_trail[i] = (x, y, life - 1)
                
                # 移除过期的轨迹点
                self.mouse_trail = [(x, y, life) for x, y, life in self.mouse_trail if life > 0]
            
            # 更新准确率
            total_shots = self.targets_hit + self.targets_missed
            if total_shots > 0:
                self.accuracy = (self.targets_hit / total_shots) * 100
    
    def handle_click(self, mouse_x, mouse_y):
        """处理鼠标点击"""
        if self.state == STATE_PLAYING:
            if self.game_mode == "reaction_test":
                # 反应测试模式
                reaction_time = self.reaction_test.record_reaction()
                if reaction_time > 0:
                    self.reaction_times.append(reaction_time)
                    self.calculate_average_reaction_time()
                    self.add_particles(mouse_x, mouse_y, SUCCESS_COLOR)
                return
            
            # 检查是否点击到目标
            target_hit = False
            for target in self.targets[:]:
                if target.is_clicked(mouse_x, mouse_y):
                    # 计算分数
                    size_bonus = int((TARGET_MAX_SIZE / target.size) * 10)  # 越小分数越高
                    time_bonus = int((target.lifetime / target.max_lifetime) * 5)  # 越早点击分数越高
                    combo_bonus = self.combo * 2
                    
                    points = 10 + size_bonus + time_bonus + combo_bonus
                    self.score += points
                    
                    # 记录命中
                    self.targets_hit += 1
                    self.combo += 1
                    self.max_combo = max(self.max_combo, self.combo)
                    
                    # 记录反应时间（如果目标刚出现）
                    if target.max_lifetime - target.lifetime < 0.5:
                        reaction_time = (target.max_lifetime - target.lifetime) * 1000
                        self.reaction_times.append(reaction_time)
                        self.calculate_average_reaction_time()
                    
                    # 击中效果
                    target.hit()
                    self.targets.remove(target)
                    self.add_particles(mouse_x, mouse_y, SUCCESS_COLOR)
                    
                    # 添加分数飘字
                    self.add_score_popup(mouse_x, mouse_y, points)
                    
                    target_hit = True
                    
                    if self.sound_effects and 'hit' in self.sounds:
                        self.sounds['hit'].play()
                    
                    break
            
            if not target_hit:
                # 未命中
                self.targets_missed += 1
                self.combo = 0
                self.add_particles(mouse_x, mouse_y, FAIL_COLOR)
                
                if self.sound_effects and 'miss' in self.sounds:
                    self.sounds['miss'].play()
            
            # 播放点击音效
            if self.sound_effects and 'click' in self.sounds:
                self.sounds['click'].play()
    
    def calculate_average_reaction_time(self):
        """计算平均反应时间"""
        if self.reaction_times:
            self.average_reaction_time = sum(self.reaction_times) / len(self.reaction_times)
    
    def calculate_final_stats(self):
        """计算最终统计"""
        self.calculate_average_reaction_time()
        
        # 更新最高分
        if self.score > self.high_score:
            self.high_score = self.score
    
    def add_particles(self, x, y, color):
        """添加粒子效果"""
        for _ in range(15):
            angle = random.random() * 2 * math.pi
            speed = random.uniform(2, 6)
            vx = math.cos(angle) * speed
            vy = math.sin(angle) * speed
            lifetime = random.randint(20, 40)
            
            self.particles.append([x, y, vx, vy, lifetime, color])
    
    def add_score_popup(self, x, y, points):
        """添加分数飘字效果"""
        # 这里可以扩展为更复杂的飘字系统
        self.particles.append([x, y - 20, 0, -1, 30, (255, 255, 200)])
    
    def start_game(self, mode="timed"):
        """开始新游戏"""
        self.state = STATE_COUNTDOWN
        self.game_mode = mode
        self.score = 0
        self.time_left = GAME_DURATION
        self.targets_hit = 0
        self.targets_missed = 0
        self.accuracy = 100.0
        self.combo = 0
        self.max_combo = 0
        self.reaction_times = []
        self.average_reaction_time = 0
        self.targets = []
        self.particles = []
        self.mouse_trail = []
        self.countdown = 3
        
        if mode != "reaction_test":
            self.generate_initial_targets()
    
    def draw(self, screen):
        """绘制游戏"""
        # 绘制背景
        screen.fill(BACKGROUND)
        
        # 绘制网格
        if self.show_grid and self.state in [STATE_PLAYING, STATE_COUNTDOWN]:
            self.draw_grid(screen)
        
        # 绘制鼠标轨迹
        if self.show_traces and self.mouse_trail:
            self.draw_mouse_trail(screen)
        
        # 绘制粒子
        for particle in self.particles:
            px, py, vx, vy, lifetime, color = particle
            if len(color) == 4:
                # RGBA颜色
                particle_surface = pygame.Surface((8, 8), pygame.SRCALPHA)
                radius = max(1, lifetime // 5)
                pygame.draw.circle(particle_surface, color, (4, 4), radius)
                screen.blit(particle_surface, (int(px) - 4, int(py) - 4))
            else:
                radius = max(1, lifetime // 5)
                pygame.draw.circle(screen, color, (int(px), int(py)), radius)
        
        # 绘制目标
        for target in self.targets:
            target.draw(screen)
        
        # 绘制反应测试
        if self.game_mode == "reaction_test" and self.state == STATE_PLAYING:
            self.reaction_test.draw(screen)
        
        # 绘制UI
        self.draw_ui(screen)
        
        # 绘制状态特定的界面
        if self.state == STATE_MENU:
            self.draw_menu(screen)
        elif self.state == STATE_COUNTDOWN:
            self.draw_countdown(screen)
        elif self.state == STATE_GAME_OVER:
            self.draw_game_over(screen)
        elif self.state == STATE_RESULTS:
            self.draw_results(screen)
    
    def draw_grid(self, screen):
        """绘制网格"""
        grid_size = 50
        for x in range(0, SCREEN_WIDTH, grid_size):
            pygame.draw.line(screen, GRID_COLOR, (x, 0), (x, SCREEN_HEIGHT), 1)
        for y in range(0, SCREEN_HEIGHT, grid_size):
            pygame.draw.line(screen, GRID_COLOR, (0, y), (SCREEN_WIDTH, y), 1)
        
        # 绘制中心十字
        center_x, center_y = SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2
        pygame.draw.line(screen, (GRID_COLOR[0], GRID_COLOR[1], GRID_COLOR[2], 150), 
                       (center_x - 20, center_y), (center_x + 20, center_y), 2)
        pygame.draw.line(screen, (GRID_COLOR[0], GRID_COLOR[1], GRID_COLOR[2], 150), 
                       (center_x, center_y - 20), (center_x, center_y + 20), 2)
    
    def draw_mouse_trail(self, screen):
        """绘制鼠标轨迹"""
        for i, (x, y, life) in enumerate(self.mouse_trail):
            if i > 0:
                prev_x, prev_y, prev_life = self.mouse_trail[i-1]
                alpha = int(life * 12)  # 根据生命周期计算透明度
                width = max(1, int(life / 5))
                
                # 创建线段表面
                line_surface = pygame.Surface((abs(x - prev_x) + width, abs(y - prev_y) + width), 
                                            pygame.SRCALPHA)
                
                # 绘制线段
                pygame.draw.line(line_surface, (255, 255, 255, alpha), 
                               (0, 0), (x - prev_x, y - prev_y), width)
                
                screen.blit(line_surface, (min(x, prev_x), min(y, prev_y)))
    
    def draw_ui(self, screen):
        """绘制用户界面"""
        if self.state in [STATE_PLAYING, STATE_COUNTDOWN]:
            # 创建UI背景
            ui_height = 100
            ui_surface = pygame.Surface((SCREEN_WIDTH, ui_height), pygame.SRCALPHA)
            ui_surface.fill(UI_BG)
            screen.blit(ui_surface, (0, 0))
            
            # 绘制分隔线
            pygame.draw.line(screen, (100, 100, 100), 
                           (0, ui_height), (SCREEN_WIDTH, ui_height), 2)
            
            # 分数
            score_text = self.font_medium.render(f"分数: {self.score}", True, TEXT_COLOR)
            screen.blit(score_text, (20, 20))
            
            # 最高分
            high_score_text = self.font_small.render(f"最高分: {self.high_score}", True, (255, 255, 200))
            screen.blit(high_score_text, (20, 60))
            
            # 时间（限时模式）
            if self.game_mode == "timed":
                time_color = (255, 200, 100) if self.time_left > 10 else (255, 100, 100)
                time_text = self.font_medium.render(f"时间: {int(self.time_left)}s", True, time_color)
                screen.blit(time_text, (SCREEN_WIDTH - 150, 20))
            
            # 命中统计
            stats_x = SCREEN_WIDTH // 2 - 100
            stats = [
                f"命中: {self.targets_hit}",
                f"未命中: {self.targets_missed}",
                f"准确率: {self.accuracy:.1f}%"
            ]
            
            for i, text in enumerate(stats):
                stat_text = self.font_small.render(text, True, TEXT_COLOR)
                screen.blit(stat_text, (stats_x, 20 + i * 25))
            
            # 连击
            if self.combo > 1:
                combo_color = (255, 100, 255) if self.combo >= 10 else (255, 200, 100)
                combo_text = self.font_medium.render(f"{self.combo} 连击!", True, combo_color)
                screen.blit(combo_text, (SCREEN_WIDTH - 200, 60))
                
                # 连击加成
                if self.combo >= 5:
                    bonus = self.combo * 2
                    bonus_text = self.font_small.render(f"+{bonus} 连击加成", True, (255, 255, 100))
                    screen.blit(bonus_text, (SCREEN_WIDTH - 200, 90))
            
            # 反应时间
            if self.reaction_times:
                react_color = (100, 255, 100) if self.average_reaction_time < 300 else \
                            (255, 200, 100) if self.average_reaction_time < 500 else \
                            (255, 100, 100)
                react_text = self.font_small.render(f"平均反应: {self.average_reaction_time:.0f}ms", True, react_color)
                screen.blit(react_text, (SCREEN_WIDTH - 300, 60))
            
            # 难度
            diff_text = self.font_small.render(f"难度: {self.difficulty}", True, TEXT_COLOR)
            screen.blit(diff_text, (SCREEN_WIDTH - 300, 20))
    
    def draw_menu(self, screen):
        """绘制主菜单"""
        # 半透明覆盖层
        overlay = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT), pygame.SRCALPHA)
        overlay.fill((0, 0, 0, 150))
        screen.blit(overlay, (0, 0))
        
        # 标题
        title = self.font_large.render("鼠标点击训练", True, (255, 255, 200))
        screen.blit(title, (SCREEN_WIDTH//2 - title.get_width()//2, 80))
        
        # 副标题
        subtitle = self.font_small.render("提高你的反应速度和准确性", True, (200, 200, 255))
        screen.blit(subtitle, (SCREEN_WIDTH//2 - subtitle.get_width()//2, 150))
        
        # 游戏模式选择
        mode_y = 220
        modes = [
            ("⏱️ 限时模式", "在60秒内尽可能获得高分"),
            ("∞ 无尽模式", "无限时间，测试你的持久力"),
            ("⚡ 反应测试", "测量你的反应时间"),
            ("🎯 准确度训练", "只计算准确率，不计时")
        ]
        
        for i, (name, desc) in enumerate(modes):
            mode_rect = pygame.Rect(SCREEN_WIDTH//2 - 200, mode_y + i*80, 400, 60)
            
            # 绘制模式按钮
            mode_color = (70, 130, 180) if i == 0 else (60, 60, 100)
            pygame.draw.rect(screen, mode_color, mode_rect, border_radius=10)
            pygame.draw.rect(screen, (100, 160, 210), mode_rect, 3, border_radius=10)
            
            # 模式名称
            name_text = self.font_medium.render(name, True, TEXT_COLOR)
            screen.blit(name_text, (mode_rect.x + 20, mode_rect.y + 10))
            
            # 模式描述
            desc_text = self.font_tiny.render(desc, True, (200, 200, 200))
            screen.blit(desc_text, (mode_rect.x + 20, mode_rect.y + 40))
        
        # 难度选择
        diff_y = mode_y + len(modes)*80 + 20
        diff_text = self.font_medium.render(f"难度: {self.difficulty}", True, TEXT_COLOR)
        screen.blit(diff_text, (SCREEN_WIDTH//2 - 100, diff_y))
        
        # 难度按钮
        for i, diff in enumerate(DIFFICULTY_LEVELS):
            diff_rect = pygame.Rect(SCREEN_WIDTH//2 - 250 + i*100, diff_y + 50, 80, 40)
            
            # 按钮颜色
            if diff == self.difficulty:
                diff_color = (100, 200, 100)
            else:
                diff_color = (80, 80, 120)
            
            pygame.draw.rect(screen, diff_color, diff_rect, border_radius=5)
            pygame.draw.rect(screen, (120, 120, 180), diff_rect, 2, border_radius=5)
            
            # 难度文本
            diff_name = self.font_tiny.render(diff, True, TEXT_COLOR)
            screen.blit(diff_name, (diff_rect.centerx - diff_name.get_width()//2, 
                                  diff_rect.centery - diff_name.get_height()//2))
        
        # 设置
        settings_y = diff_y + 120
        settings = [
            ("显示网格", self.show_grid),
            ("显示鼠标轨迹", self.show_traces),
            ("音效", self.sound_effects)
        ]
        
        for i, (name, value) in enumerate(settings):
            setting_rect = pygame.Rect(SCREEN_WIDTH//2 - 150 + i*150, settings_y, 40, 40)
            
            # 复选框
            pygame.draw.rect(screen, (60, 60, 100), setting_rect, border_radius=5)
            pygame.draw.rect(screen, (100, 100, 160), setting_rect, 2, border_radius=5)
            
            if value:
                # 勾选标记
                pygame.draw.line(screen, (100, 255, 100), 
                               (setting_rect.x + 5, setting_rect.centery),
                               (setting_rect.centerx, setting_rect.bottom - 5), 3)
                pygame.draw.line(screen, (100, 255, 100), 
                               (setting_rect.centerx, setting_rect.bottom - 5),
                               (setting_rect.right - 5, setting_rect.y + 5), 3)
            
            # 设置名称
            name_text = self.font_small.render(name, True, TEXT_COLOR)
            screen.blit(name_text, (setting_rect.x + 50, setting_rect.centery - name_text.get_height()//2))
        
        # 开始按钮
        start_rect = pygame.Rect(SCREEN_WIDTH//2 - 100, settings_y + 80, 200, 60)
        pygame.draw.rect(screen, (70, 180, 70), start_rect, border_radius=10)
        pygame.draw.rect(screen, (100, 210, 100), start_rect, 3, border_radius=10)
        
        start_text = self.font_medium.render("开始游戏", True, TEXT_COLOR)
        screen.blit(start_text, (start_rect.centerx - start_text.get_width()//2, 
                               start_rect.centery - start_text.get_height()//2))
        
        # 控制说明
        controls_y = SCREEN_HEIGHT - 100
        controls = [
            "游戏控制: 鼠标点击目标",
            "ESC: 返回菜单  P: 暂停  R: 重新开始"
        ]
        
        for i, text in enumerate(controls):
            control_text = self.font_tiny.render(text, True, (200, 200, 200))
            screen.blit(control_text, (SCREEN_WIDTH//2 - control_text.get_width()//2, 
                                     controls_y + i*25))
    
    def draw_countdown(self, screen):
        """绘制倒计时"""
        overlay = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT), pygame.SRCALPHA)
        overlay.fill((0, 0, 0, 100))
        screen.blit(overlay, (0, 0))
        
        countdown_text = self.font_large.render(str(int(self.countdown) + 1), True, (255, 200, 100))
        screen.blit(countdown_text, (SCREEN_WIDTH//2 - countdown_text.get_width()//2, 
                                   SCREEN_HEIGHT//2 - countdown_text.get_height()//2))
        
        ready_text = self.font_medium.render("准备!", True, (200, 200, 255))
        screen.blit(ready_text, (SCREEN_WIDTH//2 - ready_text.get_width()//2, 
                               SCREEN_HEIGHT//2 + 80))
    
    def draw_game_over(self, screen):
        """绘制游戏结束界面"""
        overlay = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT), pygame.SRCALPHA)
        overlay.fill((0, 0, 0, 150))
        screen.blit(overlay, (0, 0))
        
        # 游戏结束文字
        game_over = self.font_large.render("游戏结束", True, (255, 100, 100))
        screen.blit(game_over, (SCREEN_WIDTH//2 - game_over.get_width()//2, 100))
        
        # 最终分数
        score_text = self.font_medium.render(f"最终分数: {self.score}", True, TEXT_COLOR)
        screen.blit(score_text, (SCREEN_WIDTH//2 - score_text.get_width()//2, 180))
        
        if self.score > self.high_score:
            new_record = self.font_medium.render("新纪录!", True, (255, 255, 100))
            screen.blit(new_record, (SCREEN_WIDTH//2 - new_record.get_width()//2, 220))
        
        # 统计信息
        stats_y = 280
        stats = [
            f"命中目标: {self.targets_hit}",
            f"未命中: {self.targets_missed}",
            f"准确率: {self.accuracy:.1f}%",
            f"最大连击: {self.max_combo}",
            f"平均反应时间: {self.average_reaction_time:.0f}ms" if self.reaction_times else "平均反应时间: N/A"
        ]
        
        for i, text in enumerate(stats):
            stat_text = self.font_small.render(text, True, TEXT_COLOR)
            screen.blit(stat_text, (SCREEN_WIDTH//2 - 150, stats_y + i*40))
        
        # 重新开始按钮
        restart_rect = pygame.Rect(SCREEN_WIDTH//2 - 150, 500, 300, 60)
        pygame.draw.rect(screen, (70, 130, 180), restart_rect, border_radius=10)
        pygame.draw.rect(screen, (100, 160, 210), restart_rect, 3, border_radius=10)
        
        restart_text = self.font_medium.render("重新开始 (R)", True, TEXT_COLOR)
        screen.blit(restart_text, (restart_rect.centerx - restart_text.get_width()//2, 
                                 restart_rect.centery - restart_text.get_height()//2))
        
        # 返回菜单按钮
        menu_rect = pygame.Rect(SCREEN_WIDTH//2 - 150, 580, 300, 50)
        pygame.draw.rect(screen, (100, 100, 150), menu_rect, border_radius=10)
        pygame.draw.rect(screen, (130, 130, 180), menu_rect, 3, border_radius=10)
        
        menu_text = self.font_small.render("返回菜单 (ESC)", True, TEXT_COLOR)
        screen.blit(menu_text, (menu_rect.centerx - menu_text.get_width()//2, 
                              menu_rect.centery - menu_text.get_height()//2))
    
    def draw_results(self, screen):
        """绘制详细结果界面"""
        self.draw_game_over(screen)  # 重用游戏结束界面
        
        # 添加详细统计
        details_y = 400
        if self.reaction_times:
            # 反应时间分布
            times_text = self.font_small.render("反应时间分布:", True, (200, 200, 255))
            screen.blit(times_text, (SCREEN_WIDTH//2 - 150, details_y))
            
            # 最佳、平均、最差
            best = min(self.reaction_times)
            worst = max(self.reaction_times)
            
            times_stats = [
                f"最快: {best:.0f}ms",
                f"最慢: {worst:.0f}ms",
                f"平均: {self.average_reaction_time:.0f}ms"
            ]
            
            for i, text in enumerate(times_stats):
                time_text = self.font_tiny.render(text, True, TEXT_COLOR)
                screen.blit(time_text, (SCREEN_WIDTH//2 - 150, details_y + 30 + i*25))
            
            # 反应时间评级
            rating = "超凡" if self.average_reaction_time < 200 else \
                    "优秀" if self.average_reaction_time < 300 else \
                    "良好" if self.average_reaction_time < 400 else \
                    "一般" if self.average_reaction_time < 500 else "有待提高"
            
            rating_color = (100, 255, 100) if self.average_reaction_time < 300 else \
                          (255, 255, 100) if self.average_reaction_time < 400 else \
                          (255, 150, 100) if self.average_reaction_time < 500 else \
                          (255, 100, 100)
            
            rating_text = self.font_small.render(f"评级: {rating}", True, rating_color)
            screen.blit(rating_text, (SCREEN_WIDTH//2 + 50, details_y))

def main():
    clock = pygame.time.Clock()
    game = Game()
    
    # 隐藏鼠标光标
    pygame.mouse.set_visible(True)
    
    # 主游戏循环
    running = True
    while running:
        dt = clock.tick(FPS) / 1000.0
        
        # 处理事件
        for event in pygame.event.get():
            if event.type == QUIT:
                running = False
            
            elif event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    if game.state in [STATE_PLAYING, STATE_GAME_OVER, STATE_RESULTS]:
                        game.state = STATE_MENU
                    else:
                        running = False
                
                elif event.key == K_r and game.state in [STATE_PLAYING, STATE_GAME_OVER]:
                    game.start_game(game.game_mode)
                
                elif event.key == K_p and game.state == STATE_PLAYING:
                    # 暂停/继续
                    pass
                
                elif event.key == K_m and game.state == STATE_MENU:
                    # 切换音效
                    game.sound_effects = not game.sound_effects
            
            elif event.type == MOUSEBUTTONDOWN:
                if event.button == 1:  # 左键点击
                    mouse_x, mouse_y = event.pos
                    
                    if game.state == STATE_MENU:
                        # 检查菜单点击
                        # 难度选择
                        for i, diff in enumerate(DIFFICULTY_LEVELS):
                            diff_rect = pygame.Rect(SCREEN_WIDTH//2 - 250 + i*100, 370, 80, 40)
                            if diff_rect.collidepoint(mouse_x, mouse_y):
                                game.difficulty = diff
                        
                        # 设置复选框
                        settings_y = 490
                        settings = [
                            (SCREEN_WIDTH//2 - 150, "show_grid"),
                            (SCREEN_WIDTH//2, "show_traces"),
                            (SCREEN_WIDTH//2 + 150, "sound_effects")
                        ]
                        
                        for x, setting_name in settings:
                            setting_rect = pygame.Rect(x, settings_y, 40, 40)
                            if setting_rect.collidepoint(mouse_x, mouse_y):
                                setattr(game, setting_name, not getattr(game, setting_name))
                        
                        # 开始按钮
                        start_rect = pygame.Rect(SCREEN_WIDTH//2 - 100, 570, 200, 60)
                        if start_rect.collidepoint(mouse_x, mouse_y):
                            game.start_game("timed")
                        
                        # 游戏模式按钮
                        mode_y = 220
                        for i in range(4):
                            mode_rect = pygame.Rect(SCREEN_WIDTH//2 - 200, mode_y + i*80, 400, 60)
                            if mode_rect.collidepoint(mouse_x, mouse_y):
                                modes = ["timed", "endless", "reaction_test", "accuracy"]
                                game.start_game(modes[i])
                    
                    elif game.state == STATE_GAME_OVER:
                        # 检查游戏结束界面点击
                        restart_rect = pygame.Rect(SCREEN_WIDTH//2 - 150, 500, 300, 60)
                        if restart_rect.collidepoint(mouse_x, mouse_y):
                            game.start_game(game.game_mode)
                        
                        menu_rect = pygame.Rect(SCREEN_WIDTH//2 - 150, 580, 300, 50)
                        if menu_rect.collidepoint(mouse_x, mouse_y):
                            game.state = STATE_MENU
                    
                    elif game.state == STATE_PLAYING:
                        # 游戏中的点击
                        game.handle_click(mouse_x, mouse_y)
        
        # 更新游戏状态
        game.update(dt)
        
        # 绘制游戏
        game.draw(screen)
        
        # 更新显示
        pygame.display.flip()
    
    pygame.quit()
    sys.exit()

if __name__ == "__main__":
    main()