"""
051. 滑雪模拟器 - 增强版 (Ski Simulator Enhanced)
功能更丰富、画面更精美的2D滑雪游戏
"""

import pygame
import random
import math
import sys
import os

# ==================== 初始化 ====================
pygame.init()
pygame.mixer.init(frequency=22050, size=-16, channels=2, buffer=512)

# 屏幕设置
WIDTH, HEIGHT = 900, 650
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("051. 滑雪模拟器 - 增强版")

# 颜色常量
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (220, 50, 50)
YELLOW = (255, 215, 0)
GOLD = (255, 200, 0)
ORANGE = (255, 140, 0)
BLUE = (50, 100, 200)
SKY_BLUE = (135, 206, 235)
DARK_BLUE = (15, 40, 80)
TREE_GREEN = (34, 139, 34)
GREEN = (50, 180, 50)
PURPLE = (147, 112, 219)
GRAY = (128, 128, 128)
BROWN = (139, 90, 43)
SNOW_WHITE = (250, 250, 255)
PINK = (255, 100, 150)
CYAN = (100, 255, 255)
LIME = (50, 255, 50)

# 字体
try:
    font_tiny = pygame.font.SysFont("simhei", 18)
    font_small = pygame.font.SysFont("simhei", 24)
    font_medium = pygame.font.SysFont("simhei", 36)
    font_large = pygame.font.SysFont("simhei", 72)
    font_title = pygame.font.SysFont("simhei", 96)
    font_huge = pygame.font.SysFont("simhei", 120)
except:
    font_tiny = pygame.font.Font(None, 18)
    font_small = pygame.font.Font(None, 24)
    font_medium = pygame.font.Font(None, 36)
    font_large = pygame.font.Font(None, 72)
    font_title = pygame.font.Font(None, 96)
    font_huge = pygame.font.Font(None, 120)

clock = pygame.time.Clock()
FPS = 60
TIME_STEP = 1.0 / FPS

# ==================== 音效系统 ====================
class SoundManager:
    """简易音效管理器"""
    def __init__(self):
        self.enabled = True
        self.sounds = {}
        self._create_sounds()

    def _create_sounds(self):
        """用pygame生成简易音效"""
        try:
            # 跳跃音效
            self.sounds['jump'] = self._make_tone(440, 0.15, 'square')
            # 收集金币
            self.sounds['coin'] = self._make_tone(880, 0.1, 'sine')
            # 碰撞
            self.sounds['crash'] = self._make_tone(150, 0.3, 'sawtooth')
            # 旗门通过
            self.sounds['flag'] = self._make_tone(660, 0.08, 'sine')
            # 加速
            self.sounds['boost'] = self._make_tone(300, 0.2, 'triangle')
        except:
            self.enabled = False

    def _make_tone(self, freq, duration, wave_type='sine'):
        """生成简易波形"""
        sample_rate = 22050
        n_samples = int(sample_rate * duration)
        buf = bytearray()
        for i in range(n_samples):
            t = i / sample_rate
            phase = 2 * math.pi * freq * t
            if wave_type == 'sine':
                val = math.sin(phase)
            elif wave_type == 'square':
                val = 1 if math.sin(phase) > 0 else -1
            elif wave_type == 'triangle':
                val = 2 * abs(2 * (t * freq - math.floor(t * freq + 0.5))) - 1
            elif wave_type == 'sawtooth':
                val = 2 * (t * freq - math.floor(t * freq)) - 1
            else:
                val = math.sin(phase)
            buf.append(int(128 + 127 * val * 0.3))
        return pygame.mixer.Sound(buffer=bytes(buf))

    def play(self, name):
        if self.enabled and name in self.sounds:
            try:
                self.sounds[name].play()
            except:
                pass

sound_mgr = SoundManager()

# ==================== 粒子系统 ====================
class Particle:
    """基础粒子"""
    def __init__(self, x, y, color, size, vx, vy, life, gravity=0, fade=True):
        self.x = x
        self.y = y
        self.color = color
        self.size = size
        self.vx = vx
        self.vy = vy
        self.life = life
        self.max_life = life
        self.gravity = gravity
        self.fade = fade
        self.alpha = 255
        self.rotation = random.uniform(0, 360)
        self.rot_speed = random.uniform(-5, 5)

    def update(self):
        self.x += self.vx
        self.y += self.vy
        self.vy += self.gravity
        self.life -= 1
        self.rotation += self.rot_speed
        if self.fade:
            self.alpha = int(255 * (self.life / self.max_life))

    def draw(self, surface):
        if self.life <= 0 or self.alpha <= 0:
            return
        s = pygame.Surface((self.size * 2 + 2, self.size * 2 + 2), pygame.SRCALPHA)
        pygame.draw.circle(s, (*self.color, self.alpha), (self.size + 1, self.size + 1), self.size)
        surface.blit(s, (int(self.x - self.size - 1), int(self.y - self.size - 1)))

    def is_dead(self):
        return self.life <= 0

class Snowflake:
    """雪花"""
    def __init__(self):
        self.reset()
        self.y = random.randint(-HEIGHT, HEIGHT)

    def reset(self):
        self.x = random.randint(-50, WIDTH + 50)
        self.y = random.randint(-100, -10)
        self.size = random.randint(1, 4)
        self.speed_y = random.uniform(0.5, 3)
        self.speed_x = random.uniform(-0.5, 0.5)
        self.wind = random.uniform(-0.3, 0.3)
        self.alpha = random.randint(150, 255)
        self.wobble = random.uniform(0, math.pi * 2)
        self.wobble_speed = random.uniform(0.02, 0.05)

    def update(self, scroll_offset=0):
        self.wobble += self.wobble_speed
        self.x += self.speed_x + math.sin(self.wobble) * 0.5 + self.wind
        self.y += self.speed_y + scroll_offset * 0.3

        if self.y > HEIGHT + 20:
            self.reset()
        if self.x < -60:
            self.x = WIDTH + 60
        elif self.x > WIDTH + 60:
            self.x = -60

    def draw(self, surface):
        s = pygame.Surface((self.size * 2 + 2, self.size * 2 + 2), pygame.SRCALPHA)
        pygame.draw.circle(s, (255, 255, 255, self.alpha), (self.size + 1, self.size + 1), self.size)
        surface.blit(s, (int(self.x - self.size - 1), int(self.y - self.size - 1)))

# ==================== 滑雪者 ====================
class Skier:
    """滑雪者角色"""
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.width = 28
        self.height = 48
        self.vx = 0
        self.vy = 0
        self.base_speed = 4
        self.max_speed = 14
        self.accel = 0.12
        self.turn_speed = 5
        self.angle = 0
        self.target_angle = 0

        # 跳跃
        self.jumping = False
        self.jump_vy = 0
        self.jump_height = 0
        self.air_rotation = 0
        self.air_rot_speed = 0

        # 状态
        self.boost_active = False
        self.boost_timer = 0
        self.invincible = 0
        self.trick_score = 0

        # 视觉
        self.suit_colors = [RED, BLUE, PURPLE, GREEN]
        self.suit_color = RED
        self.ski_colors = [YELLOW, CYAN, PINK, GOLD]
        self.ski_color = YELLOW
        self.trail = []
        self.leg_phase = 0

    def handle_input(self, keys):
        """处理输入"""
        # 左右转向
        if keys[pygame.K_LEFT] or keys[pygame.K_a]:
            self.vx = max(self.vx - 0.5, -self.turn_speed)
            self.target_angle = -20
        elif keys[pygame.K_RIGHT] or keys[pygame.K_d]:
            self.vx = min(self.vx + 0.5, self.turn_speed)
            self.target_angle = 20
        else:
            self.vx *= 0.9
            self.target_angle = 0

        # 加速
        if keys[pygame.K_UP] or keys[pygame.K_w]:
            self.vy = min(self.vy + self.accel * 1.5, self.max_speed)
        else:
            self.vy = min(self.vy + self.accel * 0.8, self.base_speed + 2)

        # 减速
        if keys[pygame.K_DOWN] or keys[pygame.K_s]:
            self.vy = max(self.vy - self.accel * 0.5, self.base_speed * 0.5)

        # 跳跃
        if (keys[pygame.K_SPACE] or keys[pygame.K_k]) and not self.jumping and self.jump_height == 0:
            self._jump(8)
            sound_mgr.play('jump')

        # 冲刺
        if keys[pygame.K_LSHIFT] or keys[pygame.K_RSHIFT]:
            if self.boost_timer <= 0:
                self.boost_active = True
                self.boost_timer = 180  # 3秒
                self.vy = min(self.vy + 3, self.max_speed * 1.3)
                sound_mgr.play('boost')

    def _jump(self, power):
        self.jumping = True
        self.jump_vy = -power
        self.air_rot_speed = self.vx * 0.8

    def update(self, dt):
        # 角度平滑
        self.angle += (self.target_angle - self.angle) * 0.15

        # 位置更新
        self.x += self.vx * dt * 0.6
        self.x = max(self.width, min(WIDTH - self.width, self.x))

        # 跳跃物理
        if self.jumping:
            self.jump_height += self.jump_vy * dt * 0.6
            self.jump_vy += 0.5 * dt * 0.6  # 重力
            self.air_rotation += self.air_rot_speed * dt * 0.6

            if self.jump_height >= 0:
                self.jump_height = 0
                self.jumping = False
                self.air_rotation = 0
                self.air_rot_speed = 0
                # 落地粒子
                self._spawn_landing_particles()

        # 冲刺
        if self.boost_timer > 0:
            self.boost_timer -= dt
            self.boost_active = True
            if self.boost_timer <= 0:
                self.boost_active = False

        # 无敌时间
        if self.invincible > 0:
            self.invincible -= dt

        # 腿部动画
        self.leg_phase += dt * 0.3 * (1 + abs(self.vx) * 0.1)

        # 尾迹
        if abs(self.vy) > 1 and not self.jumping:
            self.trail.append({
                'x': self.x + random.uniform(-6, 6),
                'y': self.y + self.height // 2,
                'life': 20,
                'max_life': 20,
                'size': random.uniform(2, 5)
            })

        # 更新尾迹
        for t in self.trail:
            t['life'] -= dt * 0.5
        self.trail = [t for t in self.trail if t['life'] > 0]

    def _spawn_landing_particles(self):
        """落地粒子效果"""
        for _ in range(15):
            p = Particle(
                self.x + random.uniform(-10, 10),
                self.y + self.height // 2,
                WHITE, random.randint(2, 5),
                random.uniform(-3, 3), random.uniform(-4, -1),
                random.randint(15, 30), gravity=0.2
            )
            game_particles.append(p)

    def draw(self, surface):
        # 闪烁效果
        if self.invincible > 0 and int(self.invincible / 4) % 2 == 0:
            return

        y_pos = self.y - self.jump_height

        # 绘制尾迹
        for t in self.trail:
            alpha = int(200 * (t['life'] / t['max_life']))
            s = pygame.Surface((int(t['size'] * 2), int(t['size'] * 2)), pygame.SRCALPHA)
            pygame.draw.circle(s, (255, 255, 255, alpha), (int(t['size']), int(t['size'])), int(t['size']))
            surface.blit(s, (int(t['x'] - t['size']), int(t['y'] - t['size'])))

        if self.jumping:
            self._draw_airborne(surface, y_pos)
        else:
            self._draw_grounded(surface, y_pos)

        # 冲刺特效
        if self.boost_active:
            for offset in [(-15, -5), (15, -5)]:
                alpha = random.randint(100, 200)
                s = pygame.Surface((20, 8), pygame.SRCALPHA)
                pygame.draw.ellipse(s, (255, 200, 50, alpha), (0, 0, 20, 8))
                angle = math.degrees(math.atan2(-self.vy, -abs(self.vx) - 1)) + 180
                s = pygame.transform.rotate(s, angle)
                surface.blit(s, (int(self.x + offset[0] - 10), int(y_pos + offset[1])))

    def _draw_grounded(self, surface, y):
        tilt = self.angle * 0.5
        leg_offset = math.sin(self.leg_phase) * 3

        # 雪板
        for dx in [-1, 1]:
            ski_y = y + self.height // 2 + dx * leg_offset
            pygame.draw.line(surface, self.ski_color,
                            (int(self.x - 14 + tilt), int(ski_y)),
                            (int(self.x + 14 + tilt + dx * 3), int(ski_y + 2)),
                            4)
            # 滑雪板尖端翘起
            pygame.draw.circle(surface, self.ski_color,
                             (int(self.x + 14 + tilt + dx * 3), int(ski_y + 1)), 3)

        # 身体
        body_w, body_h = 14, 28
        body_rect = pygame.Rect(int(self.x - body_w // 2 + tilt * 0.3), int(y - body_h // 2), body_w, body_h)
        pygame.draw.ellipse(surface, self.suit_color, body_rect)
        # 身体高光
        hl_rect = pygame.Rect(int(self.x - body_w // 2 + tilt * 0.3 + 2), int(y - body_h // 2 + 2), 3, body_h - 8)
        pygame.draw.ellipse(surface, (255, 255, 255, 80), hl_rect)

        # 头部
        head_x = int(self.x + tilt * 0.4)
        head_y = int(y - body_h // 2 - 6)
        pygame.draw.circle(surface, (255, 210, 170), (head_x, head_y), 9)

        # 头盔
        helmet_points = [
            (head_x - 9, head_y - 2),
            (head_x - 7, head_y - 10),
            (head_x + 7, head_y - 10),
            (head_x + 9, head_y - 2),
        ]
        pygame.draw.polygon(surface, self.suit_color, helmet_points)
        # 头盔高光
        pygame.draw.arc(surface, (255, 255, 255, 100), (head_x - 6, head_y - 10, 8, 6), 0, math.pi, 2)

        # 护目镜
        goggle_color = CYAN if self.boost_active else (50, 50, 80)
        pygame.draw.rect(surface, goggle_color, (head_x - 6, head_y - 4, 12, 5), border_radius=2)
        pygame.draw.rect(surface, (100, 255, 255, 150), (head_x - 5, head_y - 3, 4, 3), border_radius=1)

        # 围巾
        scarf_color = RED if self.suit_color != RED else YELLOW
        scarf_points = [
            (head_x - 5, head_y + 4),
            (head_x + 5, head_y + 4),
            (head_x + 8, head_y + 10),
            (head_x - 3, head_y + 8),
        ]
        pygame.draw.polygon(surface, scarf_color, scarf_points)
        # 飘动的围巾尾
        wave = math.sin(self.leg_phase * 2) * 3
        pygame.draw.line(surface, scarf_color,
                       (head_x + 6, head_y + 7),
                       (head_x + 14 + int(wave), head_y + 4), 3)

        # 手臂和滑雪杖
        arm_angle = math.sin(self.leg_phase * 0.8) * 15
        for dx in [-1, 1]:
            arm_x = int(self.x + dx * 6 + tilt * 0.3)
            arm_y = int(y - 5)
            hand_x = int(arm_x + dx * (8 + arm_angle * 0.3))
            hand_y = int(arm_y + 12)
            pygame.draw.line(surface, self.suit_color, (arm_x, arm_y), (hand_x, hand_y), 4)
            # 手套
            pygame.draw.circle(surface, (50, 50, 50), (hand_x, hand_y), 3)
            # 滑雪杖
            pole_end_x = hand_x + dx * 2
            pole_end_y = hand_y + 18
            pygame.draw.line(surface, GRAY, (hand_x, hand_y), (pole_end_x, pole_end_y), 2)
            # 杖尖
            pygame.draw.circle(surface, BLACK, (pole_end_x, pole_end_y), 2)

    def _draw_airborne(self, surface, y):
        """空中绘制（带旋转）"""
        size = 70
        temp = pygame.Surface((size * 2, size * 2), pygame.SRCALPHA)
        cx, cy = size, size

        # 雪板
        pygame.draw.line(temp, self.ski_color, (cx - 14, cy + 20), (cx + 14, cy + 25), 5)
        pygame.draw.line(temp, self.ski_color, (cx - 14, cy + 22), (cx + 14, cy + 27), 5)

        # 身体
        pygame.draw.ellipse(temp, self.suit_color, (cx - 8, cy - 8, 16, 28))
        # 头部
        pygame.draw.circle(temp, (255, 210, 170), (cx, cy - 16), 9)
        # 头盔
        pygame.draw.arc(temp, self.suit_color, (cx - 8, cy - 24, 16, 12), math.pi, math.pi * 2, 3)
        # 护目镜
        pygame.draw.rect(temp, CYAN, (cx - 6, cy - 18, 12, 4))

        # 手臂张开（飞翔姿态）
        pygame.draw.line(temp, self.suit_color, (cx - 6, cy - 2), (cx - 20, cy - 8), 4)
        pygame.draw.line(temp, self.suit_color, (cx + 6, cy - 2), (cx + 20, cy - 8), 4)

        rotated = pygame.transform.rotate(temp, self.air_rotation)
        rect = rotated.get_rect(center=(int(self.x), int(y)))
        surface.blit(rotated, rect)

        # 空气动力学粒子
        for _ in range(2):
            px = self.x + random.uniform(-15, 15)
            py = y + random.uniform(-10, 20)
            p = Particle(px, py, (200, 230, 255), random.randint(1, 3),
                       random.uniform(-2, 2), random.uniform(1, 3),
                       random.randint(10, 20), fade=True)
            game_particles.append(p)

    def get_rect(self):
        offset = 5
        return pygame.Rect(int(self.x - self.width // 2 + offset), int(self.y - self.height // 2 + offset),
                          self.width - offset * 2, self.height - offset * 2)

    def change_appearance(self):
        """切换外观"""
        idx = self.suit_colors.index(self.suit_color)
        self.suit_color = self.suit_colors[(idx + 1) % len(self.suit_colors)]
        self.ski_color = self.ski_colors[(idx + 1) % len(self.ski_colors)]

# 全局粒子列表
game_particles = []

# ==================== 障碍物 ====================
class ObstacleManager:
    """障碍物管理器"""
    def __init__(self):
        self.obstacles = []
        self.spawn_timer = 0
        self.difficulty = 1.0

    def update(self, dt, scroll_speed, distance):
        self.difficulty = 1.0 + distance / 2000

        # 生成新障碍物
        self.spawn_timer -= dt
        if self.spawn_timer <= 0:
            self._spawn(distance)
            self.spawn_timer = max(30, 80 - int(distance / 50))

        # 更新所有障碍物
        for obs in self.obstacles:
            obs.update(scroll_speed, dt)

        # 清理
        self.obstacles = [o for o in self.obstacles if o.y < HEIGHT + 150]

    def _spawn(self, distance):
        """生成障碍物"""
        # 确定可生成区域（避开滑雪者位置）
        margin = 60
        available_x = list(range(margin, WIDTH - margin, 40))

        # 难度越高，障碍物越多
        num_obstacles = random.choices([1, 2, 3], weights=[60, 30, 10])[0]
        num_obstacles = min(num_obstacles + int(self.difficulty - 1), 4)

        chosen_x = random.sample(available_x, min(num_obstacles, len(available_x)))

        for x in chosen_x:
            r = random.random()
            diff_factor = min(self.difficulty, 3.0)

            if r < 0.30:
                obs = Tree(x, -50)
            elif r < 0.50:
                obs = Rock(x, -50)
            elif r < 0.65:
                obs = Flag(x, -50, random.choice([RED, BLUE, GREEN]))
            elif r < 0.80:
                obs = Coin(x, -50)
            elif r < 0.90:
                obs = JumpRamp(x, -50)
            else:
                obs = SnowDrift(x, -50)

            self.obstacles.append(obs)

    def draw(self, surface):
        for obs in sorted(self.obstacles, key=lambda o: o.y):
            obs.draw(surface)

    def check_collisions(self, skier):
        """碰撞检测，返回碰撞类型"""
        skier_rect = skier.get_rect()
        results = []

        for obs in self.obstacles:
            if obs.scored or obs.passed:
                continue
            if skier_rect.colliderect(obs.get_rect()):
                results.append(obs)
                obs.scored = True

        return results

    def reset(self):
        self.obstacles.clear()
        self.spawn_timer = 0
        self.difficulty = 1.0

class Tree:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.type = 'tree'
        self.scored = False
        self.passed = False
        self.size = random.randint(45, 75)
        self.sway = random.uniform(0, math.pi * 2)

    def update(self, scroll_speed, dt):
        self.y += scroll_speed * dt * 0.6
        self.sway += dt * 0.02

    def draw(self, surface):
        s = self.size
        sway = math.sin(self.sway) * 3

        # 阴影
        pygame.draw.ellipse(surface, (200, 200, 210), (int(self.x - s * 0.3), int(self.y + s * 0.15), int(s * 0.6), 8))

        # 树干
        trunk_w = max(3, s // 12)
        pygame.draw.rect(surface, (101, 67, 33), (int(self.x - trunk_w // 2 + sway), int(self.y - s * 0.1), trunk_w, int(s * 0.35)))

        # 多层树冠
        layers = [
            (0, -s * 0.95, s * 0.38, TREE_GREEN),
            (0, -s * 0.7, s * 0.42, (25, 120, 25)),
            (0, -s * 0.45, s * 0.45, (20, 100, 20)),
        ]
        for lx, ly, lw, color in layers:
            points = [
                (int(self.x + lx + sway), int(self.y + ly)),
                (int(self.x + lx - lw + sway), int(self.y + ly + s * 0.25)),
                (int(self.x + lx + lw + sway), int(self.y + ly + s * 0.25)),
            ]
            pygame.draw.polygon(surface, color, points)

        # 雪顶
        for lx, ly, lw, _ in layers[:2]:
            pygame.draw.line(surface, WHITE,
                           (int(self.x + lx + sway - lw * 0.5), int(self.y + ly + s * 0.05)),
                           (int(self.x + lx + sway + lw * 0.5), int(self.y + ly + s * 0.05)),
                           2)

    def get_rect(self):
        s = self.size
        return pygame.Rect(int(self.x - s * 0.3), int(self.y - s * 0.9), int(s * 0.6), int(s * 0.95))

class Rock:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.type = 'rock'
        self.scored = False
        self.passed = False
        self.size = random.randint(20, 45)

    def update(self, scroll_speed, dt):
        self.y += scroll_speed * dt * 0.6

    def draw(self, surface):
        s = self.size
        # 阴影
        pygame.draw.ellipse(surface, (200, 200, 210), (int(self.x - s * 0.4), int(self.y + s * 0.15), int(s * 0.8), 6))

        # 岩石主体
        points = [
            (int(self.x - s * 0.5), int(self.y + s * 0.1)),
            (int(self.x - s * 0.3), int(self.y - s * 0.5)),
            (int(self.x + s * 0.1), int(self.y - s * 0.7)),
            (int(self.x + s * 0.4), int(self.y - s * 0.4)),
            (int(self.x + s * 0.45), int(self.y + s * 0.05)),
            (int(self.x + s * 0.2), int(self.y + s * 0.15)),
            (int(self.x - s * 0.2), int(self.y + s * 0.15)),
        ]
        pygame.draw.polygon(surface, (100, 100, 110), points)
        pygame.draw.polygon(surface, (140, 140, 150), [(p[0], p[1] - 2) for p in points[:4]])

        # 雪盖
        snow_points = [
            (int(self.x - s * 0.2), int(self.y - s * 0.5)),
            (int(self.x), int(self.y - s * 0.7)),
            (int(self.x + s * 0.3), int(self.y - s * 0.45)),
            (int(self.x + s * 0.1), int(self.y - s * 0.35)),
        ]
        pygame.draw.polygon(surface, WHITE, snow_points)

    def get_rect(self):
        s = self.size
        return pygame.Rect(int(self.x - s * 0.4), int(self.y - s * 0.6), int(s * 0.8), int(s * 0.7))

class Flag:
    def __init__(self, x, y, color=RED):
        self.x = x
        self.y = y
        self.type = 'flag'
        self.color = color
        self.scored = False
        self.passed = False
        self.bob = random.uniform(0, math.pi * 2)
        self.pole_height = 35

    def update(self, scroll_speed, dt):
        self.y += scroll_speed * dt * 0.6
        self.bob += dt * 0.005

    def draw(self, surface):
        t = pygame.time.get_ticks() * 0.005 + self.bob
        bob = math.sin(t) * 3
        pole_h = self.pole_height

        # 旗杆阴影
        pygame.draw.line(surface, (200, 200, 200), (int(self.x + 2), int(self.y - pole_h + bob + 2)),
                       (int(self.x + 2), int(self.y + bob + 2)), 2)

        # 旗杆
        pygame.draw.line(surface, WHITE, (int(self.x), int(self.y - pole_h + bob)),
                       (int(self.x), int(self.y + bob)), 3)

        # 旗子飘动
        wave = math.sin(t * 2) * 3
        flag_points = [
            (int(self.x), int(self.y - pole_h + 5 + bob)),
            (int(self.x + 20), int(self.y - pole_h + 10 + bob + wave)),
            (int(self.x + 18), int(self.y - pole_h + 18 + bob)),
            (int(self.x), int(self.y - pole_h + 15 + bob)),
        ]
        pygame.draw.polygon(surface, self.color, flag_points)

        # 旗子高光
        hl_points = [
            (int(self.x), int(self.y - pole_h + 5 + bob)),
            (int(self.x + 10), int(self.y - pole_h + 8 + bob + wave * 0.5)),
            (int(self.x), int(self.y - pole_h + 10 + bob)),
        ]
        lighter = tuple(min(255, c + 50) for c in self.color)
        pygame.draw.polygon(surface, lighter, hl_points)

        # 底座
        pygame.draw.circle(surface, GOLD, (int(self.x), int(self.y + bob)), 4)
        pygame.draw.circle(surface, YELLOW, (int(self.x), int(self.y + bob)), 2)

    def get_rect(self):
        return pygame.Rect(int(self.x - 5), int(self.y - self.pole_height - 5), 28, self.pole_height + 10)

class Coin:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.type = 'coin'
        self.scored = False
        self.passed = False
        self.radius = 12
        self.bob = random.uniform(0, math.pi * 2)
        self.spin = 0

    def update(self, scroll_speed, dt):
        self.y += scroll_speed * dt * 0.6
        self.spin += dt * 0.1

    def draw(self, surface):
        t = pygame.time.get_ticks() * 0.008 + self.bob
        bob = math.sin(t) * 5
        spin_scale = abs(math.cos(self.spin))

        r = max(3, int(self.radius * spin_scale))

        # 光晕
        for gr in range(self.radius + 8, self.radius, -1):
            alpha = int(60 * (1 - (gr - self.radius) / 8))
            s = pygame.Surface((gr * 2, gr * 2), pygame.SRCALPHA)
            pygame.draw.circle(s, (255, 255, 150, alpha), (gr, gr), gr)
            surface.blit(s, (int(self.x - gr), int(self.y + bob - gr)))

        # 金币
        pygame.draw.circle(surface, GOLD, (int(self.x), int(self.y + bob)), self.radius)
        pygame.draw.circle(surface, YELLOW, (int(self.x), int(self.y + bob)), self.radius - 3)
        pygame.draw.circle(surface, (255, 240, 100), (int(self.x - 2), int(self.y + bob - 2)), 3)

        # $ 符号
        if spin_scale > 0.5:
            text = font_tiny.render("$", True, (200, 150, 0))
            text_rect = text.get_rect(center=(int(self.x), int(self.y + bob)))
            surface.blit(text, text_rect)

    def get_rect(self):
        return pygame.Rect(int(self.x - self.radius), int(self.y - self.radius),
                          self.radius * 2, self.radius * 2)

class JumpRamp:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.type = 'ramp'
        self.scored = False
        self.passed = False
        self.width = 90
        self.height = 35

    def update(self, scroll_speed, dt):
        self.y += scroll_speed * dt * 0.6

    def draw(self, surface):
        w, h = self.width // 2, self.height

        # 阴影
        pygame.draw.ellipse(surface, (200, 200, 210), (int(self.x - w - 5), int(self.y + h * 0.3), w * 2 + 10, 10))

        # 斜坡主体
        points = [
            (int(self.x - w), int(self.y + h * 0.3)),
            (int(self.x + w), int(self.y + h * 0.3)),
            (int(self.x + w * 0.6), int(self.y - h * 0.7)),
            (int(self.x - w * 0.6), int(self.y - h * 0.7)),
        ]
        pygame.draw.polygon(surface, ORANGE, points)

        # 高光
        hl_points = [
            (int(self.x - w * 0.5), int(self.y - h * 0.5)),
            (int(self.x + w * 0.4), int(self.y - h * 0.5)),
            (int(self.x + w * 0.3), int(self.y - h * 0.6)),
            (int(self.x - w * 0.4), int(self.y - h * 0.6)),
        ]
        pygame.draw.polygon(surface, (255, 180, 50), hl_points)

        # 边缘
        pygame.draw.line(surface, YELLOW, (int(self.x - w), int(self.y + h * 0.3)),
                       (int(self.x - w * 0.6), int(self.y - h * 0.7)), 3)
        pygame.draw.line(surface, YELLOW, (int(self.x + w), int(self.y + h * 0.3)),
                       (int(self.x + w * 0.6), int(self.y - h * 0.7)), 3)

        # 箭头标记
        arrow_t = pygame.time.get_ticks() * 0.01
        for i, ax in enumerate(range(int(self.x - w * 0.4), int(self.x + w * 0.5), 18)):
            offset = math.sin(arrow_t + i) * 3
            ay = int(self.y - h * 0.2 + offset)
            pygame.draw.line(surface, WHITE, (ax, ay), (ax + 6, ay - 6), 2)
            pygame.draw.line(surface, WHITE, (ax + 6, ay - 6), (ax + 12, ay), 2)

    def get_rect(self):
        return pygame.Rect(int(self.x - self.width // 2), int(self.y - self.height), self.width, self.height + 10)

class SnowDrift:
    """雪堆 - 无害但会减速"""
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.type = 'snowdrift'
        self.scored = False
        self.passed = False
        self.size = random.randint(25, 40)

    def update(self, scroll_speed, dt):
        self.y += scroll_speed * dt * 0.6

    def draw(self, surface):
        s = self.size
        # 雪堆形状
        points = []
        for i in range(12):
            angle = i / 12 * math.pi
            r = s * (0.6 + 0.4 * math.sin(angle * 3))
            px = self.x + r * math.cos(angle - math.pi / 2)
            py = self.y + r * 0.5 * math.sin(angle - math.pi / 2)
            points.append((int(px), int(py)))

        pygame.draw.polygon(surface, (230, 240, 255), points)
        pygame.draw.polygon(surface, WHITE, [(p[0], p[1] - 2) for p in points[:6]])

        # 闪光
        if random.random() < 0.05:
            pygame.draw.circle(surface, (255, 255, 200), (int(self.x), int(self.y - s * 0.2)), 2)

    def get_rect(self):
        s = self.size
        return pygame.Rect(int(self.x - s * 0.5), int(self.y - s * 0.3), int(s), int(s * 0.6))

# ==================== 背景系统 ====================
class Background:
    """多层视差背景"""
    def __init__(self):
        self.layers = []
        for i in range(4):
            layer = {
                'peaks': self._generate_peaks(12),
                'speed': 0.1 + i * 0.12,
                'color': self._layer_color(i),
                'offset': 0,
                'height_mod': 1.0 - i * 0.15,
            }
            self.layers.append(layer)

        # 云朵
        self.clouds = []
        for _ in range(8):
            self.clouds.append({
                'x': random.randint(0, WIDTH),
                'y': random.randint(20, 200),
                'size': random.randint(30, 80),
                'speed': random.uniform(0.1, 0.5),
            })

    def _generate_peaks(self, count):
        peaks = []
        x = 0
        for _ in range(count):
            x += random.randint(80, 200)
            y = random.randint(80, 280)
            peaks.append((x, y))
        return peaks

    def _layer_color(self, layer_idx):
        colors = [
            (60, 80, 120),    # 最远 - 深蓝灰
            (80, 110, 150),   # 远
            (100, 140, 180),  # 中
            (130, 170, 210),  # 近
        ]
        return colors[layer_idx]

    def update(self, scroll_speed, dt):
        for layer in self.layers:
            layer['offset'] += scroll_speed * layer['speed'] * dt * 0.6

        for cloud in self.clouds:
            cloud['x'] -= cloud['speed'] * dt * 0.5
            if cloud['x'] < -100:
                cloud['x'] = WIDTH + 100
                cloud['y'] = random.randint(20, 200)

    def draw(self, surface):
        # 天空渐变
        for y in range(HEIGHT):
            ratio = y / HEIGHT
            r = int(135 - ratio * 80)
            g = int(206 - ratio * 120)
            b = int(235 - ratio * 40)
            pygame.draw.line(surface, (r, g, b), (0, y), (WIDTH, y))

        # 云朵
        for cloud in self.clouds:
            self._draw_cloud(surface, cloud['x'], cloud['y'], cloud['size'])

        # 远山
        for layer in self.layers:
            self._draw_mountain_layer(surface, layer)

    def _draw_cloud(self, surface, x, y, size):
        s = pygame.Surface((size * 3, size * 2), pygame.SRCALPHA)
        for dx, dy, r in [(size, size, size * 0.4), (size * 1.3, size * 0.8, size * 0.35),
                          (size * 1.6, size, size * 0.3), (size * 0.7, size * 0.7, size * 0.35)]:
            pygame.draw.circle(s, (255, 255, 255, 180), (int(dx), int(dy)), int(r))
        surface.blit(s, (int(x - size * 1.5), int(y - size)))

    def _draw_mountain_layer(self, surface, layer):
        offset = layer['offset'] % (WIDTH + 400)
        peaks = layer['peaks']
        color = layer['color']
        h_mod = layer['height_mod']

        points = [(0, HEIGHT)]
        for px, py in peaks:
            x = (px + offset) % (WIDTH + 400) - 200
            points.append((int(x), int(HEIGHT - py * h_mod)))

        # 闭合路径
        if peaks:
            last_x = (peaks[-1][0] + offset) % (WIDTH + 400) - 200
            points.append((int(last_x), HEIGHT))
        points.append((WIDTH, HEIGHT))

        pygame.draw.polygon(surface, color, points)

        # 山峰积雪
        for i in range(len(peaks) - 1):
            px1, py1 = peaks[i]
            px2, py2 = peaks[i + 1]
            mid_x = (px1 + px2) / 2
            mid_y = (py1 + py2) / 2
            x = (mid_x + offset) % (WIDTH + 400) - 200
            snow_y = HEIGHT - mid_y * h_mod
            snow_h = min(py1, py2) * h_mod * 0.3
            snow_points = [
                (int(x - 15), int(snow_y)),
                (int(x), int(snow_y - snow_h)),
                (int(x + 15), int(snow_y)),
            ]
            lighter = tuple(min(255, c + 40) for c in color)
            pygame.draw.polygon(surface, lighter, snow_points)

class SnowGround:
    """雪地渲染"""
    def __init__(self):
        self.texture_lines = []
        for _ in range(60):
            self.texture_lines.append({
                'x': random.randint(0, WIDTH),
                'y': random.randint(0, HEIGHT),
                'length': random.randint(15, 60),
                'angle': random.uniform(-0.2, 0.2),
                'alpha': random.randint(30, 100),
                'width': random.randint(1, 3),
            })
        self.ski_tracks = []

    def update(self, scroll_speed, dt):
        for line in self.texture_lines:
            line['y'] += scroll_speed * dt * 0.6
            if line['y'] > HEIGHT + 20:
                line['y'] = -20
                line['x'] = random.randint(0, WIDTH)

    def add_ski_track(self, x, y):
        self.ski_tracks.append({'x': x, 'y': y, 'life': 100})
        if len(self.ski_tracks) > 200:
            self.ski_tracks = self.ski_tracks[-200:]

    def update_tracks(self, scroll_speed, dt):
        for t in self.ski_tracks:
            t['y'] += scroll_speed * dt * 0.6
            t['life'] -= dt * 0.5
        self.ski_tracks = [t for t in self.ski_tracks if t['life'] > 0 and t['y'] < HEIGHT + 20]

    def draw(self, surface, scroll_speed=0):
        # 地面基础色
        ground_rect = pygame.Rect(0, HEIGHT // 3, WIDTH, HEIGHT * 2 // 3)
        pygame.draw.rect(surface, (240, 244, 250), ground_rect)

        # 渐变
        for y in range(HEIGHT // 3, HEIGHT, 3):
            ratio = (y - HEIGHT // 3) / (HEIGHT * 2 // 3)
            c = int(245 - ratio * 15)
            pygame.draw.line(surface, (c, c, c + 3), (0, y), (WIDTH, y))

        # 雪地纹理
        for line in self.texture_lines:
            alpha = line['alpha']
            s = pygame.Surface((line['length'], line['width'] + 2), pygame.SRCALPHA)
            pygame.draw.line(s, (255, 255, 255, alpha), (0, line['width'] // 2 + 1),
                           (line['length'], line['width'] // 2 + 1), line['width'])
            s = pygame.transform.rotate(s, math.degrees(line['angle']))
            surface.blit(s, (int(line['x']), int(line['y'])))

        # 滑雪轨迹
        for t in self.ski_tracks:
            alpha = int(80 * (t['life'] / 100))
            s = pygame.Surface((6, 6), pygame.SRCALPHA)
            pygame.draw.circle(s, (220, 225, 235, alpha), (3, 3), 3)
            surface.blit(s, (int(t['x'] - 3), int(t['y'] - 3)))

# ==================== 游戏状态 ====================
class GameState:
    """游戏状态管理"""
    MENU = "menu"
    PLAYING = "playing"
    PAUSED = "paused"
    GAME_OVER = "game_over"
    HELP = "help"
    SETTINGS = "settings"

class GameSettings:
    """游戏设置"""
    def __init__(self):
        self.sound_enabled = True
        self.snow_enabled = True
        self.shake_enabled = True
        self.difficulty = "normal"  # easy, normal, hard

# ==================== 主游戏类 ====================
class SkiSimulator:
    def __init__(self):
        self.state = GameState.MENU
        self.settings = GameSettings()
        self.skier = Skier(WIDTH // 2, HEIGHT // 2 + 50)
        self.obstacle_mgr = ObstacleManager()
        self.background = Background()
        self.ground = SnowGround()
        self.snowflakes = [Snowflake() for _ in range(120)]
        self.particles = []

        # 游戏数据
        self.score = 0
        self.distance = 0
        self.combo = 0
        self.combo_timer = 0
        self.max_combo = 0
        self.coins_collected = 0
        self.flags_passed = 0
        self.jumps_made = 0
        self.best_score = 0

        # 效果
        self.screen_shake = 0
        self.flash_alpha = 0
        self.flash_color = WHITE

        # 时间
        self.start_time = 0
        self.play_time = 0

        # UI
        self.notifications = []
        self.speed_history = []

    def start_game(self):
        self.state = GameState.PLAYING
        self.skier = Skier(WIDTH // 2, HEIGHT // 2 + 50)
        self.obstacle_mgr.reset()
        self.particles.clear()
        self.score = 0
        self.distance = 0
        self.combo = 0
        self.combo_timer = 0
        self.max_combo = 0
        self.coins_collected = 0
        self.flags_passed = 0
        self.jumps_made = 0
        self.start_time = pygame.time.get_ticks()
        self.notifications.clear()
        self._add_notification("开始滑雪!", YELLOW, 120)

    def update(self, dt):
        global game_particles

        if self.state == GameState.MENU:
            self._update_menu(dt)
        elif self.state == GameState.PLAYING:
            self._update_game(dt)
        elif self.state == GameState.GAME_OVER:
            self._update_game_over(dt)
        elif self.state == GameState.PAUSED:
            pass
        elif self.state == GameState.HELP:
            pass

        # 更新雪花（所有状态）
        scroll = self.skier.vy if self.state == GameState.PLAYING else 0
        for flake in self.snowflakes:
            flake.update(scroll * 0.3)

        # 更新粒子
        self.particles = [p for p in self.particles if not p.is_dead()]
        for p in self.particles:
            p.update()

        # 更新通知
        for n in self.notifications:
            n['life'] -= dt
            n['y'] -= dt * 0.3
        self.notifications = [n for n in self.notifications if n['life'] > 0]

        # 屏幕震动衰减
        if self.screen_shake > 0:
            self.screen_shake *= 0.9
            if self.screen_shake < 0.5:
                self.screen_shake = 0

        # 闪光衰减
        if self.flash_alpha > 0:
            self.flash_alpha -= dt * 5
            if self.flash_alpha < 0:
                self.flash_alpha = 0

    def _update_menu(self, dt):
        self.background.update(2, dt)
        self.ground.update(2, dt)

    def _update_game(self, dt):
        keys = pygame.key.get_pressed()

        # 背景
        self.background.update(self.skier.vy + 3, dt)
        self.ground.update(self.skier.vy + 3, dt)

        # 滑雪者
        self.skier.handle_input(keys)
        self.skier.update(dt)

        # 添加滑雪轨迹
        if abs(self.skier.vy) > 2 and not self.skier.jumping:
            self.ground.add_ski_track(self.skier.x - 8, self.skier.y + 20)
            self.ground.add_ski_track(self.skier.x + 8, self.skier.y + 20)

        self.ground.update_tracks(self.skier.vy + 3, dt)

        # 距离和分数
        self.distance += self.skier.vy * dt * 0.08
        self.play_time = (pygame.time.get_ticks() - self.start_time) / 1000.0

        # 基础分数（距离分）
        distance_score = int(self.distance * 0.5)
        self.score = distance_score + self._get_collected_score()

        # 障碍物
        self.obstacle_mgr.update(dt, self.skier.vy + 3, self.distance)
        self._handle_collisions()

        # Combo 计时
        if self.combo_timer > 0:
            self.combo_timer -= dt
            if self.combo_timer <= 0:
                self.combo = 0

        # 跳台检测
        self._check_ramp_trigger()

        # 速度历史
        self.speed_history.append(self.skier.vy)
        if len(self.speed_history) > 60:
            self.speed_history.pop(0)

    def _get_collected_score(self):
        """计算收集物分数"""
        return self.coins_collected * 50 + self.flags_passed * 30 + self.jumps_made * 20

    def _handle_collisions(self):
        """处理碰撞"""
        collisions = self.obstacle_mgr.check_collisions(self.skier)

        for obs in collisions:
            if obs.type == 'tree' or obs.type == 'rock':
                self._handle_obstacle_crash(obs)
            elif obs.type == 'flag':
                self._handle_flag_pass(obs)
            elif obs.type == 'coin':
                self._handle_coin_collect(obs)
            elif obs.type == 'snowdrift':
                self._handle_snowdrift(obs)

    def _handle_obstacle_crash(self, obs):
        """撞到障碍物"""
        if self.skier.invincible > 0:
            return

        self.skier.vy *= 0.4
        self.skier.invincible = 90
        self.combo = 0
        self.screen_shake = 20
        sound_mgr.play('crash')

        # 碰撞粒子
        for _ in range(25):
            p = Particle(obs.x, obs.y, WHITE, random.randint(2, 6),
                       random.uniform(-5, 5), random.uniform(-6, -1),
                       random.randint(20, 40), gravity=0.3)
            self.particles.append(p)

        # 碎片
        for _ in range(10):
            p = Particle(obs.x, obs.y, (200, 200, 200), random.randint(1, 3),
                       random.uniform(-3, 3), random.uniform(-4, 0),
                       random.randint(15, 30), gravity=0.2)
            self.particles.append(p)

        if self.skier.vy < 1.5:
            self._game_over()

        self._add_notification("碰撞! -速度", RED, 60)

    def _handle_flag_pass(self, obs):
        """穿过旗门"""
        self.flags_passed += 1
        self.combo += 1
        self.max_combo = max(self.max_combo, self.combo)
        self.combo_timer = 200
        sound_mgr.play('flag')

        points = 30 * (1 + self.combo * 0.1)
        self._add_notification(f"+{int(points)} 旗门!", (255, 100, 100), 60)

        # 旗门粒子
        for _ in range(8):
            p = Particle(obs.x, obs.y - 20, obs.color, random.randint(2, 4),
                       random.uniform(-2, 2), random.uniform(-3, -1),
                       random.randint(15, 25), gravity=-0.05)
            self.particles.append(p)

    def _handle_coin_collect(self, obs):
        """收集金币"""
        self.coins_collected += 1
        self.combo += 1
        self.max_combo = max(self.max_combo, self.combo)
        self.combo_timer = 200
        sound_mgr.play('coin')

        points = 50 * (1 + self.combo * 0.1)
        self._add_notification(f"+{int(points)} 金币!", GOLD, 60)

        # 金币粒子
        for _ in range(12):
            p = Particle(obs.x, obs.y, GOLD, random.randint(1, 3),
                       random.uniform(-3, 3), random.uniform(-4, -1),
                       random.randint(15, 30), gravity=-0.1)
            self.particles.append(p)

    def _handle_snowdrift(self, obs):
        """雪堆减速"""
        self.skier.vy *= 0.85
        self._add_notification("雪堆! 减速", (180, 180, 220), 40)

        # 雪花飞溅
        for _ in range(8):
            p = Particle(obs.x, obs.y, WHITE, random.randint(1, 3),
                       random.uniform(-3, 3), random.uniform(-3, 0),
                       random.randint(10, 20), gravity=0.1)
            self.particles.append(p)

    def _check_ramp_trigger(self):
        """检测跳台触发"""
        skier_rect = self.skier.get_rect()
        for obs in self.obstacle_mgr.obstacles:
            if obs.type == 'ramp' and not obs.passed:
                if skier_rect.colliderect(obs.get_rect()):
                    if not self.skier.jumping:
                        self.skier._jump(10)
                        self.jumps_made += 1
                        self.score += 20
                        obs.passed = True
                        sound_mgr.play('jump')
                        self._add_notification("跳跃! +20", CYAN, 60)

                        # 跳台粒子
                        for _ in range(15):
                            p = Particle(self.skier.x, self.skier.y + 20, WHITE, random.randint(2, 4),
                                       random.uniform(-3, 3), random.uniform(-2, 1),
                                       random.randint(15, 30), gravity=-0.05)
                            self.particles.append(p)

    def _game_over(self):
        self.state = GameState.GAME_OVER
        if self.score > self.best_score:
            self.best_score = self.score
        self.flash_color = RED
        self.flash_alpha = 150
        sound_mgr.play('crash')

    def _add_notification(self, text, color, life):
        self.notifications.append({
            'text': text,
            'color': color,
            'life': life,
            'max_life': life,
            'x': self.skier.x,
            'y': self.skier.y - 40,
        })

    def draw(self, surface):
        # 屏幕震动偏移
        shake_x = random.randint(-int(self.screen_shake), int(self.screen_shake)) if self.screen_shake > 0 else 0
        shake_y = random.randint(-int(self.screen_shake), int(self.screen_shake)) if self.screen_shake > 0 else 0

        if self.state == GameState.MENU:
            self._draw_menu(surface, shake_x, shake_y)
        elif self.state in [GameState.PLAYING, GameState.PAUSED, GameState.GAME_OVER]:
            self._draw_game(surface, shake_x, shake_y)
        elif self.state == GameState.HELP:
            self._draw_help(surface)

        # 闪光效果
        if self.flash_alpha > 0:
            s = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)
            s.fill((*self.flash_color, int(self.flash_alpha)))
            surface.blit(s, (0, 0))

    def _draw_menu(self, surface, sx, sy):
        self.background.draw(surface)
        for flake in self.snowflakes:
            flake.draw(surface)
        self.ground.draw(surface)

        # 半透明覆盖
        overlay = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)
        overlay.fill((0, 0, 30, 100))
        surface.blit(overlay, (0, 0))

        # 标题
        t = pygame.time.get_ticks() * 0.003
        bob = math.sin(t) * 8

        title = font_huge.render("滑雪模拟器", True, WHITE)
        shadow = font_huge.render("滑雪模拟器", True, (100, 100, 150))
        surface.blit(shadow, (WIDTH // 2 - title.get_width() // 2 + 3, HEIGHT // 5 + int(bob) + 3))
        surface.blit(title, (WIDTH // 2 - title.get_width() // 2, HEIGHT // 5 + int(bob)))

        # 副标题
        subtitle = font_medium.render("SKI SIMULATOR 2026", True, (180, 200, 255))
        surface.blit(subtitle, (WIDTH // 2 - subtitle.get_width() // 2, HEIGHT // 5 + 100 + int(bob)))

        # 装饰线
        for i in range(3):
            alpha = 150 - i * 40
            pygame.draw.line(surface, (255, 255, 255, alpha),
                           (WIDTH // 2 - 100 - i * 20, HEIGHT // 5 + 130 + int(bob)),
                           (WIDTH // 2 + 100 + i * 20, HEIGHT // 5 + 130 + int(bob)),
                           1)

        # 菜单选项
        options = [
            ("▶ 开始游戏", YELLOW),
            ("⚙ 操作说明", WHITE),
            ("★ 设置", CYAN),
            ("✖ 退出", (255, 150, 150)),
        ]

        for i, (text, color) in enumerate(options):
            y_pos = HEIGHT // 2 + 60 + i * 65
            is_selected = (i == menu_selected)

            if is_selected:
                # 选中背景
                bg = pygame.Surface((300, 50), pygame.SRCALPHA)
                bg.fill((255, 255, 255, 30))
                pygame.draw.rect(bg, (255, 255, 255, 80), bg.get_rect(), border_radius=10)
                surface.blit(bg, (WIDTH // 2 - 150, y_pos - 10))
                # 脉冲效果
                pulse = 1 + math.sin(t * 3) * 0.05
                text_surf = font_medium.render(text, True, YELLOW)
                text_surf = pygame.transform.scale(text_surf,
                    (int(text_surf.get_width() * pulse), int(text_surf.get_height() * pulse)))
            else:
                text_surf = font_medium.render(text, True, color)

            surface.blit(text_surf, (WIDTH // 2 - text_surf.get_width() // 2, y_pos))

        # 底部提示
        hint = font_small.render("↑↓ 选择   Enter 确认   ESC 退出", True, (180, 180, 200))
        surface.blit(hint, (WIDTH // 2 - hint.get_width() // 2, HEIGHT - 60))

        # 版本
        ver = font_tiny.render("v2.0 Enhanced", True, (120, 120, 150))
        surface.blit(ver, (WIDTH - 80, HEIGHT - 30))

    def _draw_game(self, surface, sx, sy):
        # 背景
        self.background.draw(surface)

        # 雪花（背景层）
        for flake in self.snowflakes[:60]:
            flake.draw(surface)

        # 地面
        self.ground.draw(surface, self.skier.vy)

        # 障碍物
        self.obstacle_mgr.draw(surface)

        # 滑雪者
        self.skier.draw(surface)

        # 粒子
        for p in self.particles:
            p.draw(surface)

        # 雪花（前景层）
        for flake in self.snowflakes[60:]:
            flake.draw(surface)

        # UI
        self._draw_hud(surface)

        # 通知
        self._draw_notifications(surface)

        # 暂停覆盖
        if self.state == GameState.PAUSED:
            self._draw_pause_overlay(surface)

        # 游戏结束覆盖
        if self.state == GameState.GAME_OVER:
            self._draw_game_over_screen(surface)

    def _draw_hud(self, surface):
        """绘制游戏HUD"""
        # 顶部信息栏背景
        hud_bg = pygame.Surface((WIDTH, 50), pygame.SRCALPHA)
        hud_bg.fill((0, 0, 0, 80))
        surface.blit(hud_bg, (0, 0))

        # 分数
        score_text = font_medium.render(f"{self.score}", True, YELLOW)
        surface.blit(score_text, (20, 10))

        # 距离
        dist_text = font_small.render(f"🏔 {int(self.distance)}m", True, WHITE)
        surface.blit(dist_text, (160, 18))

        # Combo
        if self.combo > 1:
            combo_scale = 1 + math.sin(pygame.time.get_ticks() * 0.01) * 0.15
            combo_text = font_medium.render(f"x{self.combo}", True, GOLD)
            combo_surf = pygame.transform.scale(combo_text,
                (int(combo_text.get_width() * combo_scale), int(combo_text.get_height() * combo_scale)))
            surface.blit(combo_surf, (WIDTH // 2 - combo_surf.get_width() // 2, 5))

            # Combo 条
            bar_w = 100
            ratio = self.combo_timer / 200
            pygame.draw.rect(surface, (80, 60, 20), (WIDTH // 2 - bar_w // 2, 42, bar_w, 4), border_radius=2)
            pygame.draw.rect(surface, GOLD, (WIDTH // 2 - bar_w // 2, 42, int(bar_w * ratio), 4), border_radius=2)

        # 速度计（右侧）
        speed = int(self.skier.vy * 12)
        speed_text = font_small.render(f"{speed} km/h", True, WHITE)
        surface.blit(speed_text, (WIDTH - 120, 15))

        # 速度条
        bar_h = 100
        bar_w = 12
        bar_x = WIDTH - 30
        bar_y = HEIGHT - 120
        pygame.draw.rect(surface, (50, 50, 60), (bar_x, bar_y, bar_w, bar_h), border_radius=3)
        speed_ratio = min(self.skier.vy / self.skier.max_speed, 1.5) / 1.5
        fill_h = int(bar_h * speed_ratio)
        speed_color = (int(255 * speed_ratio), int(255 * (1 - speed_ratio * 0.7)), 0)
        pygame.draw.rect(surface, speed_color, (bar_x, bar_y + bar_h - fill_h, bar_w, fill_h), border_radius=3)
        # 刻度
        for i in range(1, 4):
            ky = bar_y + bar_h * i // 4
            pygame.draw.line(surface, WHITE, (bar_x - 3, ky), (bar_x, ky), 1)

        # 冲刺指示
        if self.skier.boost_active:
            boost_ratio = self.skier.boost_timer / 180
            boost_text = font_tiny.render("BOOST!", True, ORANGE)
            surface.blit(boost_text, (WIDTH - 80, 40))
            pygame.draw.rect(surface, (80, 50, 0), (WIDTH - 80, 55, 60, 5), border_radius=2)
            pygame.draw.rect(surface, ORANGE, (WIDTH - 80, 55, int(60 * boost_ratio), 5), border_radius=2)

        # 金币计数
        coin_text = font_small.render(f"💰 {self.coins_collected}", True, GOLD)
        surface.blit(coin_text, (WIDTH - 200, 18))

        # 操作提示（底部）
        if self.distance < 200:
            hint = font_tiny.render("← → 转向 | ↑ 加速 | ↓ 减速 | SPACE 跳跃 | SHIFT 冲刺", True, (200, 200, 220))
            surface.blit(hint, (WIDTH // 2 - hint.get_width() // 2, HEIGHT - 30))

    def _draw_notifications(self, surface):
        for n in self.notifications:
            alpha = int(255 * (n['life'] / n['max_life']))
            text = font_small.render(n['text'], True, n['color'])
            s = pygame.Surface(text.get_size(), pygame.SRCALPHA)
            s.fill((0, 0, 0, alpha // 3))
            s.blit(text, (0, 0))
            x = int(n['x'] - text.get_width() // 2)
            y = int(n['y'])
            surface.blit(s, (x - 4, y - 2))
            text.set_alpha(alpha)
            surface.blit(text, (x, y))

    def _draw_pause_overlay(self, surface):
        overlay = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)
        overlay.fill((0, 0, 0, 160))
        surface.blit(overlay, (0, 0))

        # 暂停图标
        pause_bg = pygame.Surface((200, 200), pygame.SRCALPHA)
        pygame.draw.circle(pause_bg, (255, 255, 255, 40), (100, 100), 80)
        surface.blit(pause_bg, (WIDTH // 2 - 100, HEIGHT // 2 - 100))

        text = font_large.render("暂停", True, WHITE)
        surface.blit(text, (WIDTH // 2 - text.get_width() // 2, HEIGHT // 2 - 30))

        hint = font_small.render("按 P 继续 | ESC 返回菜单", True, (200, 200, 200))
        surface.blit(hint, (WIDTH // 2 - hint.get_width() // 2, HEIGHT // 2 + 50))

    def _draw_game_over_screen(self, surface):
        overlay = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)
        overlay.fill((0, 0, 0, 180))
        surface.blit(overlay, (0, 0))

        # 标题
        text = font_title.render("GAME OVER", True, RED)
        # 阴影
        shadow = font_title.render("GAME OVER", True, (100, 0, 0))
        surface.blit(shadow, (WIDTH // 2 - text.get_width() // 2 + 3, HEIGHT // 3 - 47))
        surface.blit(text, (WIDTH // 2 - text.get_width() // 2, HEIGHT // 3 - 50))

        # 数据面板
        panel_w, panel_h = 400, 250
        panel_x = WIDTH // 2 - panel_w // 2
        panel_y = HEIGHT // 3 + 30

        panel = pygame.Surface((panel_w, panel_h), pygame.SRCALPHA)
        panel.fill((20, 20, 40, 200))
        pygame.draw.rect(panel, (255, 255, 255, 50), panel.get_rect(), border_radius=15, width=2)
        surface.blit(panel, (panel_x, panel_y))

        stats = [
            (f"最终分数: {self.score}", YELLOW, 25),
            (f"滑行距离: {int(self.distance)}m", WHITE, 65),
            (f"收集金币: {self.coins_collected}", GOLD, 100),
            (f"通过旗门: {self.flags_passed}", (255, 100, 100), 130),
            (f"跳跃次数: {self.jumps_made}", CYAN, 160),
            (f"最高连击: x{self.max_combo}", ORANGE, 190),
        ]

        for text, color, y_off in stats:
            t = font_small.render(text, True, color)
            surface.blit(t, (panel_x + panel_w // 2 - t.get_width() // 2, panel_y + y_off))

        # 最高分
        if self.score >= self.best_score and self.score > 0:
            best_text = font_medium.render("🏆 新纪录!", True, GOLD)
            surface.blit(best_text, (WIDTH // 2 - best_text.get_width() // 2, panel_y + panel_h + 15))

        best_t = font_small.render(f"历史最高: {self.best_score}", True, (200, 200, 200))
        surface.blit(best_t, (WIDTH // 2 - best_t.get_width() // 2, panel_y + panel_h + 50))

        # 提示
        t = pygame.time.get_ticks() * 0.005
        alpha = int(200 + math.sin(t) * 55)
        hint_surf = font_medium.render("按 R 重新开始   ESC 返回菜单", True, WHITE)
        hint_surf.set_alpha(alpha)
        surface.blit(hint_surf, (WIDTH // 2 - hint_surf.get_width() // 2, HEIGHT - 100))

    def _draw_help(self, surface):
        surface.fill(DARK_BLUE)

        for flake in self.snowflakes:
            flake.draw(surface)

        # 标题
        title = font_large.render("操作说明", True, WHITE)
        surface.blit(title, (WIDTH // 2 - title.get_width() // 2, 30))

        # 分割线
        pygame.draw.line(surface, (100, 130, 180), (200, 85), (WIDTH - 200, 85), 2)

        # 操作表
        instructions = [
            ("← → / A D", "左右转向", "control"),
            ("↑ / W", "加速下坡", "control"),
            ("↓ / S", "减速刹车", "control"),
            ("SPACE / K", "跳跃", "action"),
            ("SHIFT", "冲刺加速 (限时)", "action"),
            ("P", "暂停游戏", "system"),
            ("R", "重新开始", "system"),
            ("ESC", "返回菜单", "system"),
        ]

        y = 110
        for key, desc, cat in instructions:
            cat_colors = {'control': CYAN, 'action': ORANGE, 'system': (180, 180, 255)}
            cat_color = cat_colors.get(cat, WHITE)

            # 分类标签
            cat_label = font_tiny.render(cat.upper(), True, cat_color)
            surface.blit(cat_label, (WIDTH // 2 - 220, y + 5))

            # 按键
            key_bg = pygame.Surface((120, 26), pygame.SRCALPHA)
            key_bg.fill((255, 255, 255, 30))
            pygame.draw.rect(key_bg, cat_color, key_bg.get_rect(), border_radius=4, width=1)
            key_text = font_small.render(key, True, WHITE)
            key_bg.blit(key_text, (60 - key_text.get_width() // 2, 3))
            surface.blit(key_bg, (WIDTH // 2 - 100, y))

            # 描述
            desc_text = font_small.render(desc, True, (220, 220, 220))
            surface.blit(desc_text, (WIDTH // 2 + 40, y + 4))

            y += 40

        # 游戏提示
        y += 20
        pygame.draw.line(surface, (100, 130, 180), (200, y), (WIDTH - 200, y), 1)
        y += 15

        tips = [
            "🏔  避开树木和岩石，碰撞会大幅减速",
            "🚩  穿过旗门获得分数和连击加成",
            "💰  收集金币可获得大量分数",
            "🏂  利用跳台进行跳跃，展现特技",
            "❄  注意雪堆会减速但不会结束游戏",
            "🔥  连击越多，得分倍率越高",
        ]

        for tip in tips:
            t = font_small.render(tip, True, (200, 220, 240))
            surface.blit(t, (WIDTH // 2 - 200, y))
            y += 32

        # 返回提示
        hint = font_medium.render("按 ESC 返回菜单", True, GOLD)
        surface.blit(hint, (WIDTH // 2 - hint.get_width() // 2, HEIGHT - 60))

    def _update_game_over(self, dt):
        """游戏结束界面也更新背景"""
        self.background.update(1, dt)
        # 让粒子继续运动
        self.particles = [p for p in self.particles if not p.is_dead()]
        for p in self.particles:
            p.update()

# ==================== 主循环 ====================
def main():
    global menu_selected

    game = SkiSimulator()
    menu_selected = 0

    running = True
    while running:
        dt = min(clock.tick(FPS) / 1000.0 * 60, 3.0)  # 标准化到60fps，限制最大dt

        # 事件
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False

            elif event.type == pygame.KEYDOWN:
                if game.state == GameState.MENU:
                    if event.key == pygame.K_UP or event.key == pygame.K_w:
                        menu_selected = (menu_selected - 1) % 4
                    elif event.key == pygame.K_DOWN or event.key == pygame.K_s:
                        menu_selected = (menu_selected + 1) % 4
                    elif event.key == pygame.K_RETURN or event.key == pygame.K_SPACE:
                        if menu_selected == 0:
                            game.start_game()
                        elif menu_selected == 1:
                            game.state = GameState.HELP
                        elif menu_selected == 2:
                            # 设置 - 循环切换难度
                            difficulties = ["easy", "normal", "hard"]
                            idx = difficulties.index(game.settings.difficulty)
                            game.settings.difficulty = difficulties[(idx + 1) % 3]
                        elif menu_selected == 3:
                            running = False
                    elif event.key == pygame.K_ESCAPE:
                        running = False

                elif game.state == GameState.HELP:
                    if event.key == pygame.K_ESCAPE or event.key == pygame.K_RETURN:
                        game.state = GameState.MENU

                elif game.state == GameState.PLAYING:
                    if event.key == pygame.K_ESCAPE:
                        game.state = GameState.MENU
                    elif event.key == pygame.K_p:
                        game.state = GameState.PAUSED
                    elif event.key == pygame.K_r:
                        game.start_game()
                    elif event.key == pygame.K_TAB:
                        game.skier.change_appearance()

                elif game.state == GameState.PAUSED:
                    if event.key == pygame.K_p or event.key == pygame.K_ESCAPE:
                        game.state = GameState.PLAYING
                    elif event.key == pygame.K_ESCAPE:
                        game.state = GameState.MENU

                elif game.state == GameState.GAME_OVER:
                    if event.key == pygame.K_r or event.key == pygame.K_SPACE or event.key == pygame.K_RETURN:
                        game.start_game()
                    elif event.key == pygame.K_ESCAPE:
                        game.state = GameState.MENU

        # 更新和绘制
        game.update(dt)
        game.draw(screen)
        pygame.display.flip()

    pygame.quit()
    sys.exit()

if __name__ == "__main__":
    main()
