import pygame
import sys
import math
import random

# 初始化 Pygame
pygame.init()

# 窗口设置
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("🧈 豆腐公主")

# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 50, 50)
DARK_RED = (200, 0, 0)
PINK = (255, 182, 193)
LIGHT_PINK = (255, 220, 225)
DARK_PINK = (255, 150, 180)
YELLOW = (255, 255, 100)
GOLD = (255, 215, 0)
ORANGE = (255, 165, 0)
GREEN = (50, 200, 50)
DARK_GREEN = (0, 150, 0)
BLUE = (50, 150, 255)
LIGHT_BLUE = (173, 216, 230)
PURPLE = (200, 50, 255)
BROWN = (139, 69, 19)
LIGHT_BROWN = (160, 120, 80)
GRAY = (150, 150, 150)
DARK_GRAY = (80, 80, 80)
LIGHT_GRAY = (200, 200, 200)
SKY_BLUE = (135, 206, 235)
SOFT_YELLOW = (255, 248, 220)
CREAM = (255, 253, 240)
TOFU_WHITE = (245, 240, 235)

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

# 中文字体
def get_chinese_font(size):
    font_names = ["SimHei", "Microsoft YaHei", "PingFang SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", "Arial"]
    for name in font_names:
        try:
            return pygame.font.SysFont(name, size)
        except:
            continue
    return pygame.font.Font(None, size)

font = get_chinese_font(28)
small_font = get_chinese_font(18)
big_font = get_chinese_font(50)

# 粒子系统
class Particle:
    def __init__(self, x, y, color, vx=None, vy=None, life=30, size=4):
        self.x = x
        self.y = y
        self.vx = vx if vx is not None else random.uniform(-3, 3)
        self.vy = vy if vy is not None else random.uniform(-5, -1)
        self.life = life
        self.max_life = life
        self.size = size
        self.color = color
        self.alive = True
    
    def update(self):
        self.x += self.vx
        self.y += self.vy
        self.vy += 0.1
        self.life -= 1
        if self.life <= 0:
            self.alive = False
    
    def draw(self, surface):
        if not self.alive:
            return
        alpha = int(255 * (self.life / self.max_life))
        size = int(self.size * (self.life / self.max_life))
        # 使用set_alpha方式
        particle_surf = pygame.Surface((size * 2, size * 2), pygame.SRCALPHA)
        temp_surf = pygame.Surface((size * 2, size * 2), pygame.SRCALPHA)
        pygame.draw.circle(temp_surf, self.color, (size, size), size)
        temp_surf.set_alpha(alpha)
        particle_surf.blit(temp_surf, (0, 0))
        surface.blit(particle_surf, (int(self.x) - size, int(self.y) - size))

# 豆腐公主类
class TofuPrincess:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.width = 30
        self.height = 40
        self.vx = 0
        self.vy = 0
        self.speed = 4
        self.jump_power = -10
        self.gravity = 0.5
        self.on_ground = False
        self.facing = 1  # 1=右, -1=左
        self.hp = 100
        self.max_hp = 100
        self.energy = 100
        self.max_energy = 100
        self.score = 0
        self.invincible = 0
        self.attack_cooldown = 0
        self.dash_cooldown = 0
        self.is_dashing = False
        self.dash_timer = 0
        self.particles = []
        self.collected_items = []
        self.anim_frame = 0
        self.anim_timer = 0
        
        # 技能
        self.skills = {
            "dash": {"cooldown": 0, "max_cooldown": 60, "cost": 20},
            "heal": {"cooldown": 0, "max_cooldown": 120, "cost": 30},
        }
    
    def update(self, keys, platforms, enemies, items):
        # 无敌计时
        if self.invincible > 0:
            self.invincible -= 1
        
        # 冷却计时
        if self.attack_cooldown > 0:
            self.attack_cooldown -= 1
        if self.dash_cooldown > 0:
            self.dash_cooldown -= 1
        for skill in self.skills.values():
            if skill["cooldown"] > 0:
                skill["cooldown"] -= 1
        
        # 冲刺
        if self.is_dashing:
            self.dash_timer -= 1
            if self.dash_timer <= 0:
                self.is_dashing = False
            else:
                self.vx = self.facing * 12
                self.vy = 0
                # 冲刺粒子
                if random.random() < 0.3:
                    p = Particle(self.x - self.facing * 20, self.y, 
                               (200, 200, 255), 
                               -self.facing * random.uniform(1, 3), 
                               random.uniform(-2, 2), 15, 3)
                    self.particles.append(p)
        
        # 水平移动
        self.vx = 0
        if keys[pygame.K_LEFT] or keys[pygame.K_a]:
            self.vx = -self.speed
            self.facing = -1
        if keys[pygame.K_RIGHT] or keys[pygame.K_d]:
            self.vx = self.speed
            self.facing = 1
        
        # 跳跃
        if (keys[pygame.K_SPACE] or keys[pygame.K_w] or keys[pygame.K_UP]) and self.on_ground:
            self.vy = self.jump_power
            self.on_ground = False
            # 跳跃粒子
            for _ in range(10):
                p = Particle(self.x, self.y, (255, 240, 220), 
                           random.uniform(-2, 2), random.uniform(0, 2), 20, 3)
                self.particles.append(p)
        
        # 重力
        self.vy += self.gravity
        if self.vy > 15:
            self.vy = 15
        
        # 更新位置
        self.x += self.vx
        self.y += self.vy
        
        # 平台碰撞
        self.on_ground = False
        for platform in platforms:
            if self.check_collision(platform):
                if self.vy > 0:  # 落在平台上
                    self.y = platform.y - self.height
                    self.vy = 0
                    self.on_ground = True
                elif self.vy < 0:  # 头顶撞到平台
                    self.y = platform.y + platform.height
                    self.vy = 0
        
        # 边界限制
        self.x = max(10, min(WIDTH - self.width - 10, self.x))
        if self.y > HEIGHT + 50:
            self.hp = 0
        
        # 动画
        self.anim_timer += 1
        if abs(self.vx) > 0.5 and self.on_ground:
            if self.anim_timer > 8:
                self.anim_timer = 0
                self.anim_frame = (self.anim_frame + 1) % 4
        
        # 能量恢复
        if self.energy < self.max_energy:
            self.energy += 0.1
        if self.energy > self.max_energy:
            self.energy = self.max_energy
        
        # 更新粒子
        for p in self.particles[:]:
            p.update()
            if not p.alive:
                self.particles.remove(p)
        
        # 敌人碰撞
        for enemy in enemies:
            if enemy.alive and self.check_collision(enemy) and self.invincible == 0:
                if self.is_dashing:
                    enemy.hp -= 30
                    enemy.knockback(self.facing)
                    if enemy.hp <= 0:
                        self.score += 50
                else:
                    self.hp -= 10
                    self.invincible = 30
                    self.vy = -5
        
        # 物品收集
        for item in items[:]:
            if item.alive and self.check_collision(item):
                if item.type == "heart":
                    self.hp = min(self.max_hp, self.hp + 20)
                elif item.type == "star":
                    self.score += 100
                    self.energy = min(self.max_energy, self.energy + 30)
                elif item.type == "coin":
                    self.score += 50
                elif item.type == "power":
                    self.dash_cooldown = 0
                    self.attack_cooldown = 0
                item.alive = False
                # 收集粒子
                for _ in range(15):
                    p = Particle(item.x, item.y, GOLD, 
                               random.uniform(-5, 5), random.uniform(-5, 5), 30, 4)
                    self.particles.append(p)
    
    def check_collision(self, obj):
        # 简单的矩形碰撞检测
        return (self.x < obj.x + obj.width and 
                self.x + self.width > obj.x and 
                self.y < obj.y + obj.height and 
                self.y + self.height > obj.y)
    
    def dash(self):
        if not self.is_dashing and self.dash_cooldown <= 0 and self.energy >= 20:
            self.is_dashing = True
            self.dash_timer = 15
            self.dash_cooldown = 60
            self.energy -= 20
            self.invincible = 10
            return True
        return False
    
    def heal(self):
        if self.energy >= 30 and self.hp < self.max_hp:
            self.hp = min(self.max_hp, self.hp + 20)
            self.energy -= 30
            # 治疗粒子
            for _ in range(20):
                p = Particle(self.x + self.width//2, self.y + self.height//2, 
                           (100, 255, 100), 
                           random.uniform(-4, 4), random.uniform(-6, 0), 30, 5)
                self.particles.append(p)
            return True
        return False
    
    def draw(self, surface):
        cx, cy = self.x + self.width//2, self.y + self.height//2
        
        # 冲刺残影
        if self.is_dashing:
            for i in range(5):
                alpha = 100 - i * 20
                shadow_surf = pygame.Surface((self.width, self.height), pygame.SRCALPHA)
                temp_surf = pygame.Surface((self.width, self.height), pygame.SRCALPHA)
                pygame.draw.ellipse(temp_surf, (200, 200, 255), (0, 0, self.width, self.height))
                temp_surf.set_alpha(alpha)
                shadow_surf.blit(temp_surf, (0, 0))
                surface.blit(shadow_surf, (self.x - self.facing * i * 8, self.y))
        
        # 身体（豆腐块）
        body_surf = pygame.Surface((self.width, self.height), pygame.SRCALPHA)
        pygame.draw.rect(body_surf, TOFU_WHITE, (0, 0, self.width, self.height), border_radius=8)
        pygame.draw.rect(body_surf, (220, 215, 210), (0, 0, self.width, self.height), 2, border_radius=8)
        
        # 豆腐的纹理（小孔）
        for i in range(4):
            px = 5 + i * 7
            py = 8 + (i % 3) * 12
            pygame.draw.circle(body_surf, (230, 225, 220), (px, py), 2)
        
        # 闪烁（无敌时）
        if self.invincible > 0 and self.invincible % 6 < 3:
            body_surf.set_alpha(128)
        
        surface.blit(body_surf, (self.x, self.y))
        
        # 脸
        if self.facing == 1:
            eye_x1 = self.x + 8
            eye_x2 = self.x + 20
        else:
            eye_x1 = self.x + 10
            eye_x2 = self.x + 22
        
        eye_y = self.y + 12
        
        # 眼睛
        pygame.draw.circle(surface, BLACK, (eye_x1, eye_y), 4)
        pygame.draw.circle(surface, BLACK, (eye_x2, eye_y), 4)
        pygame.draw.circle(surface, WHITE, (eye_x1 - 1, eye_y - 1), 2)
        pygame.draw.circle(surface, WHITE, (eye_x2 - 1, eye_y - 1), 2)
        
        # 嘴
        if self.hp > 60:
            pygame.draw.arc(surface, BLACK, (self.x + 8, self.y + 18, 14, 10), 0, math.pi, 2)
        elif self.hp > 30:
            pygame.draw.line(surface, BLACK, (self.x + 10, self.y + 24), 
                           (self.x + 20, self.y + 24), 2)
        else:
            pygame.draw.arc(surface, BLACK, (self.x + 8, self.y + 22, 14, 8), math.pi, 2*math.pi, 2)
        
        # 腮红
        for ex in [self.x + 4, self.x + 24]:
            blush_surf = pygame.Surface((8, 6), pygame.SRCALPHA)
            temp_surf = pygame.Surface((8, 6), pygame.SRCALPHA)
            pygame.draw.ellipse(temp_surf, (255, 180, 200), (0, 0, 8, 6))
            temp_surf.set_alpha(80)
            blush_surf.blit(temp_surf, (0, 0))
            surface.blit(blush_surf, (ex, self.y + 18))
        
        # 皇冠（公主标志）
        crown_y = self.y - 10
        crown_points = [
            (self.x + 4, crown_y + 8),
            (self.x + 10, crown_y),
            (self.x + 15, crown_y + 6),
            (self.x + 20, crown_y),
            (self.x + 26, crown_y + 8),
        ]
        pygame.draw.polygon(surface, GOLD, crown_points)
        pygame.draw.polygon(surface, GOLD, crown_points, 2)
        
        # 皇冠上的宝石
        pygame.draw.circle(surface, RED, (self.x + 10, crown_y + 4), 3)
        pygame.draw.circle(surface, BLUE, (self.x + 15, crown_y + 6), 3)
        pygame.draw.circle(surface, GREEN, (self.x + 20, crown_y + 4), 3)
        
        # 绘制粒子
        for p in self.particles:
            p.draw(surface)
        
        # 血量条
        bar_width = 40
        bar_height = 4
        bar_x = self.x
        bar_y = self.y - 15
        pygame.draw.rect(surface, RED, (bar_x, bar_y, bar_width, bar_height))
        hp_ratio = self.hp / self.max_hp
        pygame.draw.rect(surface, GREEN, (bar_x, bar_y, bar_width * hp_ratio, bar_height))
        pygame.draw.rect(surface, BLACK, (bar_x, bar_y, bar_width, bar_height), 1)

# 平台类
class Platform:
    def __init__(self, x, y, width, height, color=None):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.color = color if color else (139, 69, 19)
    
    def draw(self, surface):
        # 平台主体
        pygame.draw.rect(surface, self.color, (self.x, self.y, self.width, self.height))
        # 高光
        highlight = pygame.Rect(self.x + 2, self.y + 2, self.width - 4, 3)
        pygame.draw.rect(surface, (200, 180, 150), highlight)

# 敌人基类
class Enemy:
    def __init__(self, x, y, enemy_type="slime"):
        self.x = x
        self.y = y
        self.width = 25
        self.height = 25
        self.type = enemy_type
        self.hp = 20
        self.max_hp = 20
        self.speed = 1.5
        self.alive = True
        self.facing = 1
        self.anim_timer = 0
        self.anim_frame = 0
        self.knockback_vx = 0
        self.knockback_vy = 0
        
        if enemy_type == "slime":
            self.color = (100, 200, 100)
            self.hp = 15
            self.max_hp = 15
            self.speed = 1
        elif enemy_type == "bat":
            self.color = (150, 80, 200)
            self.hp = 10
            self.max_hp = 10
            self.speed = 2
            self.width = 20
            self.height = 20
        elif enemy_type == "golem":
            self.color = (150, 150, 150)
            self.hp = 50
            self.max_hp = 50
            self.speed = 0.8
            self.width = 35
            self.height = 40
    
    def update(self, player, platforms):
        if not self.alive:
            return
        
        # 击退效果
        if abs(self.knockback_vx) > 0.1 or abs(self.knockback_vy) > 0.1:
            self.x += self.knockback_vx
            self.y += self.knockback_vy
            self.knockback_vx *= 0.9
            self.knockback_vy *= 0.9
            return
        
        # AI行为
        dx = player.x - self.x
        dy = player.y - self.y
        dist = math.hypot(dx, dy)
        
        if dist < 200 and dist > 20:
            if self.type == "bat":
                # 蝙蝠会飞，可以跟踪
                self.x += (dx / dist) * self.speed
                self.y += (dy / dist) * self.speed * 0.5
            elif self.type == "golem":
                # 石像鬼缓慢移动
                if abs(dx) > 50:
                    self.x += (dx / abs(dx)) * self.speed
                if random.random() < 0.02:
                    self.y += random.choice([-1, 1]) * self.speed * 0.3
            else:
                # 史莱姆只左右移动
                self.x += (dx / abs(dx)) * self.speed if abs(dx) > 10 else 0
        
        # 朝向玩家
        if player.x > self.x:
            self.facing = 1
        else:
            self.facing = -1
        
        # 动画
        self.anim_timer += 1
        if self.anim_timer > 10:
            self.anim_timer = 0
            self.anim_frame = (self.anim_frame + 1) % 4
    
    def knockback(self, direction):
        self.knockback_vx = direction * 8
        self.knockback_vy = -5
    
    def hit(self, damage):
        self.hp -= damage
        if self.hp <= 0:
            self.alive = False
    
    def draw(self, surface):
        if not self.alive:
            return
        
        if self.type == "slime":
            # 史莱姆
            for i in range(3):
                offset_y = 3 * math.sin(self.anim_frame * 0.5 + i * 0.5)
                pygame.draw.ellipse(surface, self.color, 
                                  (self.x - i*2, self.y + self.height - 15 + i*2 + offset_y, 
                                   self.width + i*4, 8))
            pygame.draw.ellipse(surface, self.color, 
                              (self.x, self.y + self.height - 20, self.width, 18))
            pygame.draw.ellipse(surface, BLACK, 
                              (self.x, self.y + self.height - 20, self.width, 18), 1)
            # 眼睛
            if self.facing == 1:
                eye_x1 = self.x + 6
                eye_x2 = self.x + 16
            else:
                eye_x1 = self.x + 4
                eye_x2 = self.x + 14
            pygame.draw.circle(surface, WHITE, (eye_x1, self.y + self.height - 12), 5)
            pygame.draw.circle(surface, WHITE, (eye_x2, self.y + self.height - 12), 5)
            pygame.draw.circle(surface, BLACK, (eye_x1 + self.facing * 2, self.y + self.height - 11), 3)
            pygame.draw.circle(surface, BLACK, (eye_x2 + self.facing * 2, self.y + self.height - 11), 3)
        
        elif self.type == "bat":
            # 蝙蝠
            wing_flap = math.sin(self.anim_frame * 0.5) * 10
            # 身体
            pygame.draw.ellipse(surface, self.color, (self.x, self.y, self.width, self.height))
            # 翅膀
            if self.facing == 1:
                pygame.draw.polygon(surface, (120, 60, 180), 
                                  [(self.x, self.y + 5), (self.x - 15, self.y - 5 + wing_flap), 
                                   (self.x - 10, self.y + 15)])
                pygame.draw.polygon(surface, (120, 60, 180), 
                                  [(self.x, self.y + self.height - 5), (self.x - 15, self.y + self.height + 5 - wing_flap), 
                                   (self.x - 10, self.y + self.height - 15)])
            else:
                pygame.draw.polygon(surface, (120, 60, 180), 
                                  [(self.x + self.width, self.y + 5), (self.x + self.width + 15, self.y - 5 + wing_flap), 
                                   (self.x + self.width + 10, self.y + 15)])
                pygame.draw.polygon(surface, (120, 60, 180), 
                                  [(self.x + self.width, self.y + self.height - 5), 
                                   (self.x + self.width + 15, self.y + self.height + 5 - wing_flap), 
                                   (self.x + self.width + 10, self.y + self.height - 15)])
            # 眼睛
            eye_y = self.y + 8
            if self.facing == 1:
                eye_x1 = self.x + 5
                eye_x2 = self.x + 13
            else:
                eye_x1 = self.x + 7
                eye_x2 = self.x + 15
            pygame.draw.circle(surface, RED, (eye_x1, eye_y), 3)
            pygame.draw.circle(surface, RED, (eye_x2, eye_y), 3)
        
        elif self.type == "golem":
            # 石像鬼
            pygame.draw.rect(surface, self.color, (self.x, self.y, self.width, self.height), border_radius=4)
            pygame.draw.rect(surface, BLACK, (self.x, self.y, self.width, self.height), 2, border_radius=4)
            # 眼睛发光
            if self.facing == 1:
                eye_x1 = self.x + 6
                eye_x2 = self.x + 22
            else:
                eye_x1 = self.x + 9
                eye_x2 = self.x + 25
            pygame.draw.circle(surface, RED, (eye_x1, self.y + 12), 5)
            pygame.draw.circle(surface, RED, (eye_x2, self.y + 12), 5)
            pygame.draw.circle(surface, (255, 200, 100), (eye_x1, self.y + 12), 3)
            pygame.draw.circle(surface, (255, 200, 100), (eye_x2, self.y + 12), 3)
            # 嘴
            pygame.draw.line(surface, BLACK, (self.x + 8, self.y + 28), 
                           (self.x + self.width - 8, self.y + 28), 2)
        
        # 血量条
        bar_width = self.width
        bar_height = 3
        bar_x = self.x
        bar_y = self.y - 8
        pygame.draw.rect(surface, RED, (bar_x, bar_y, bar_width, bar_height))
        hp_ratio = self.hp / self.max_hp
        pygame.draw.rect(surface, GREEN, (bar_x, bar_y, bar_width * hp_ratio, bar_height))

# 物品类
class Item:
    def __init__(self, x, y, item_type):
        self.x = x
        self.y = y
        self.width = 15
        self.height = 15
        self.type = item_type
        self.alive = True
        self.anim_timer = 0
        
        if item_type == "heart":
            self.color = RED
        elif item_type == "star":
            self.color = GOLD
        elif item_type == "coin":
            self.color = YELLOW
        elif item_type == "power":
            self.color = PURPLE
    
    def update(self):
        self.anim_timer += 1
        self.y += math.sin(self.anim_timer * 0.05) * 0.3
    
    def draw(self, surface):
        if not self.alive:
            return
        
        if self.type == "heart":
            # 心形
            points = []
            for i in range(20):
                t = i * 2 * math.pi / 20
                x = self.x + 8 + 8 * 16 * math.sin(t) ** 3
                y = self.y + 8 - (13 * math.cos(t) - 5 * math.cos(2*t) - 2 * math.cos(3*t) - math.cos(4*t))
                points.append((x, y))
            pygame.draw.polygon(surface, RED, points)
        
        elif self.type == "star":
            # 星星
            points = []
            for i in range(10):
                angle = i * math.pi / 5 - math.pi / 2
                if i % 2 == 0:
                    r = 10
                else:
                    r = 5
                x = self.x + 8 + r * math.cos(angle)
                y = self.y + 8 + r * math.sin(angle)
                points.append((x, y))
            pygame.draw.polygon(surface, GOLD, points)
        
        elif self.type == "coin":
            # 金币
            pygame.draw.circle(surface, YELLOW, (self.x + 8, self.y + 8), 8)
            pygame.draw.circle(surface, GOLD, (self.x + 8, self.y + 8), 6)
            pygame.draw.circle(surface, YELLOW, (self.x + 8, self.y + 8), 8, 1)
        
        elif self.type == "power":
            # 能量
            pygame.draw.circle(surface, PURPLE, (self.x + 8, self.y + 8), 8)
            pygame.draw.circle(surface, (255, 200, 255), (self.x + 8, self.y + 8), 5)
            # 闪电符号
            pygame.draw.polygon(surface, WHITE, 
                              [(self.x + 8, self.y + 2), (self.x + 10, self.y + 7),
                               (self.x + 7, self.y + 7), (self.x + 6, self.y + 12),
                               (self.x + 9, self.y + 9), (self.x + 11, self.y + 9)])

# 游戏主类
class TofuPrincessGame:
    def __init__(self):
        self.player = TofuPrincess(100, 400)
        self.platforms = []
        self.enemies = []
        self.items = []
        self.particles = []
        self.score = 0
        self.game_over = False
        self.win = False
        self.level = 1
        self.combo = 0
        self.combo_timer = 0
        
        self.create_level()
    
    def create_level(self):
        self.platforms = []
        self.enemies = []
        self.items = []
        
        # 地面平台
        self.platforms.append(Platform(0, 550, 800, 50, (100, 80, 60)))
        
        # 根据关卡生成不同的地形
        if self.level == 1:
            # 简单关卡
            platforms = [
                (100, 450, 150, 20),
                (300, 400, 150, 20),
                (500, 450, 150, 20),
                (200, 300, 120, 20),
                (450, 300, 120, 20),
                (650, 400, 100, 20),
            ]
            for x, y, w, h in platforms:
                self.platforms.append(Platform(x, y, w, h, (139, 69, 19)))
            
            # 敌人
            self.enemies.append(Enemy(200, 500, "slime"))
            self.enemies.append(Enemy(400, 500, "slime"))
            self.enemies.append(Enemy(600, 500, "slime"))
            self.enemies.append(Enemy(350, 250, "bat"))
            
            # 物品
            self.items.append(Item(150, 420, "heart"))
            self.items.append(Item(350, 370, "coin"))
            self.items.append(Item(550, 420, "star"))
            self.items.append(Item(250, 270, "coin"))
            self.items.append(Item(500, 270, "heart"))
        
        elif self.level == 2:
            # 中等关卡
            platforms = [
                (50, 480, 120, 20),
                (200, 420, 120, 20),
                (350, 350, 120, 20),
                (500, 420, 120, 20),
                (650, 480, 120, 20),
                (150, 250, 100, 20),
                (400, 220, 100, 20),
                (600, 280, 120, 20),
            ]
            for x, y, w, h in platforms:
                self.platforms.append(Platform(x, y, w, h, (139, 69, 19)))
            
            # 敌人
            self.enemies.append(Enemy(100, 450, "slime"))
            self.enemies.append(Enemy(300, 300, "bat"))
            self.enemies.append(Enemy(450, 300, "bat"))
            self.enemies.append(Enemy(550, 450, "golem"))
            self.enemies.append(Enemy(700, 450, "slime"))
            self.enemies.append(Enemy(250, 200, "bat"))
            
            # 物品
            self.items.append(Item(80, 450, "heart"))
            self.items.append(Item(230, 390, "star"))
            self.items.append(Item(380, 320, "coin"))
            self.items.append(Item(530, 390, "power"))
            self.items.append(Item(680, 450, "heart"))
            self.items.append(Item(180, 220, "coin"))
            self.items.append(Item(430, 190, "star"))
        
        elif self.level == 3:
            # 困难关卡
            platforms = [
                (0, 500, 100, 20),
                (150, 440, 100, 20),
                (300, 380, 100, 20),
                (450, 320, 100, 20),
                (600, 380, 100, 20),
                (700, 440, 100, 20),
                (100, 280, 80, 20),
                (350, 220, 100, 20),
                (550, 250, 100, 20),
                (200, 150, 80, 20),
                (450, 120, 80, 20),
            ]
            for x, y, w, h in platforms:
                self.platforms.append(Platform(x, y, w, h, (139, 69, 19)))
            
            # 敌人
            self.enemies.append(Enemy(50, 450, "slime"))
            self.enemies.append(Enemy(200, 400, "golem"))
            self.enemies.append(Enemy(350, 330, "bat"))
            self.enemies.append(Enemy(500, 270, "bat"))
            self.enemies.append(Enemy(650, 330, "golem"))
            self.enemies.append(Enemy(150, 230, "bat"))
            self.enemies.append(Enemy(400, 170, "bat"))
            self.enemies.append(Enemy(600, 200, "bat"))
            
            # 物品
            self.items.append(Item(30, 470, "heart"))
            self.items.append(Item(180, 410, "star"))
            self.items.append(Item(330, 350, "power"))
            self.items.append(Item(480, 290, "coin"))
            self.items.append(Item(630, 350, "heart"))
            self.items.append(Item(130, 250, "star"))
            self.items.append(Item(380, 190, "coin"))
            self.items.append(Item(580, 220, "power"))
            self.items.append(Item(230, 120, "heart"))
            self.items.append(Item(480, 90, "star"))
        
        # 更新玩家位置
        self.player.x = 50
        self.player.y = 500
    
    def update(self, keys):
        if self.game_over or self.win:
            if keys[pygame.K_r]:
                self.__init__()
            return
        
        # 更新玩家
        self.player.update(keys, self.platforms, self.enemies, self.items)
        
        # 更新敌人
        for enemy in self.enemies:
            enemy.update(self.player, self.platforms)
        
        # 更新物品
        for item in self.items:
            item.update()
        
        # 检查是否所有敌人被消灭
        if all(not e.alive for e in self.enemies) and self.level < 3:
            # 生成传送门（胜利条件）
            if not hasattr(self, 'portal'):
                self.portal = {"x": 750, "y": 500, "active": True}
        
        # 检查是否进入传送门
        if hasattr(self, 'portal') and self.portal["active"]:
            if (abs(self.player.x - self.portal["x"]) < 30 and 
                abs(self.player.y - self.portal["y"]) < 30):
                if self.level < 3:
                    self.level += 1
                    self.create_level()
                    delattr(self, 'portal')
                else:
                    self.win = True
        
        # 检查游戏结束
        if self.player.hp <= 0:
            self.game_over = True
    
    def draw(self, surface):
        # 背景
        gradient = pygame.Surface((WIDTH, HEIGHT))
        for y in range(HEIGHT):
            color = (200 - y * 0.1, 220 - y * 0.1, 255 - y * 0.05)
            pygame.draw.line(gradient, color, (0, y), (WIDTH, y))
        surface.blit(gradient, (0, 0))
        
        # 绘制平台
        for platform in self.platforms:
            platform.draw(surface)
        
        # 绘制物品
        for item in self.items:
            item.draw(surface)
        
        # 绘制敌人
        for enemy in self.enemies:
            enemy.draw(surface)
        
        # 绘制传送门
        if hasattr(self, 'portal') and self.portal["active"]:
            # 旋转光环
            portal_x, portal_y = self.portal["x"], self.portal["y"]
            for i in range(8):
                angle = pygame.time.get_ticks() / 500 + i * math.pi / 4
                r = 25 + 5 * math.sin(pygame.time.get_ticks() / 300 + i)
                px = portal_x + r * math.cos(angle)
                py = portal_y + r * math.sin(angle)
                pygame.draw.circle(surface, (100, 200, 255), (int(px), int(py)), 5)
            pygame.draw.circle(surface, (50, 150, 255), (portal_x, portal_y), 20, 2)
            pygame.draw.circle(surface, (100, 200, 255), (portal_x, portal_y), 15)
            label = small_font.render("下一关", True, WHITE)
            label_rect = label.get_rect(center=(portal_x, portal_y + 35))
            surface.blit(label, label_rect)
        
        # 绘制玩家
        self.player.draw(surface)
        
        # UI
        self.draw_ui(surface)
        
        # 游戏结束/胜利
        if self.game_over:
            overlay = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)
            overlay.fill((0, 0, 0, 180))
            surface.blit(overlay, (0, 0))
            
            game_over_text = big_font.render("💔 豆腐公主倒下了", True, RED)
            text_rect = game_over_text.get_rect(center=(WIDTH // 2, HEIGHT // 2 - 40))
            surface.blit(game_over_text, text_rect)
            
            restart_text = font.render("按 R 重新开始", True, WHITE)
            restart_rect = restart_text.get_rect(center=(WIDTH // 2, HEIGHT // 2 + 20))
            surface.blit(restart_text, restart_rect)
        
        if self.win:
            overlay = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)
            overlay.fill((0, 0, 0, 180))
            surface.blit(overlay, (0, 0))
            
            win_text = big_font.render("👑 恭喜通关！", True, GOLD)
            text_rect = win_text.get_rect(center=(WIDTH // 2, HEIGHT // 2 - 40))
            surface.blit(win_text, text_rect)
            
            score_text = font.render(f"最终得分: {self.player.score}", True, WHITE)
            score_rect = score_text.get_rect(center=(WIDTH // 2, HEIGHT // 2 + 20))
            surface.blit(score_text, score_rect)
            
            restart_text = font.render("按 R 重新开始", True, WHITE)
            restart_rect = restart_text.get_rect(center=(WIDTH // 2, HEIGHT // 2 + 60))
            surface.blit(restart_text, restart_rect)
    
    def draw_ui(self, surface):
        ui_bg = pygame.Surface((WIDTH, 40), pygame.SRCALPHA)
        ui_bg.fill((0, 0, 0, 100))
        surface.blit(ui_bg, (0, 0))
        
        # 血量
        hp_text = font.render(f"❤️ {int(self.player.hp)}", True, RED)
        surface.blit(hp_text, (10, 5))
        
        # 能量
        energy_text = font.render(f"⚡ {int(self.player.energy)}", True, BLUE)
        surface.blit(energy_text, (120, 5))
        
        # 得分
        score_text = font.render(f"⭐ {self.player.score}", True, GOLD)
        surface.blit(score_text, (230, 5))
        
        # 关卡
        level_text = font.render(f"🏰 第{self.level}关", True, WHITE)
        surface.blit(level_text, (380, 5))
        
        # 敌人数量
        alive_enemies = sum(1 for e in self.enemies if e.alive)
        enemy_text = font.render(f"👾 {alive_enemies}", True, (200, 100, 100))
        surface.blit(enemy_text, (520, 5))
        
        # 技能提示
        dash_ready = self.player.dash_cooldown <= 0 and self.player.energy >= 20
        heal_ready = self.player.skills["heal"]["cooldown"] <= 0 and self.player.energy >= 30
        
        dash_color = GREEN if dash_ready else GRAY
        heal_color = GREEN if heal_ready else GRAY
        
        dash_text = small_font.render(f"[Z]冲刺", True, dash_color)
        surface.blit(dash_text, (650, 5))
        
        heal_text = small_font.render(f"[X]治疗", True, heal_color)
        surface.blit(heal_text, (730, 5))
        
        # 连击
        if hasattr(self, 'combo') and self.combo > 1:
            combo_text = font.render(f"🔥 {self.combo}连击", True, ORANGE)
            surface.blit(combo_text, (WIDTH // 2 - 50, 45))

# 主游戏函数
def main():
    game = TofuPrincessGame()
    running = True
    
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_z:
                    game.player.dash()
                if event.key == pygame.K_x:
                    game.player.heal()
                if event.key == pygame.K_r:
                    game = TofuPrincessGame()
        
        keys = pygame.key.get_pressed()
        
        # 更新游戏
        game.update(keys)
        
        # 绘制
        game.draw(screen)
        pygame.display.flip()
        clock.tick(FPS)
    
    pygame.quit()
    sys.exit()

if __name__ == "__main__":
    main()