import pygame
import random
import math

# --- 初始化 ---
pygame.init()
WIDTH, HEIGHT = 400, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("是男人就上一百层 - Pygame版")
clock = pygame.time.Clock()

# 颜色
BG_COLOR = (30, 30, 40)
PLAYER_COLOR = (50, 150, 255)
PLAT_NORMAL = (150, 150, 150)
PLAT_SPRING = (50, 200, 50)
PLAT_FRAGILE = (200, 50, 50)
PLAT_MOVING = (200, 200, 50)
TEXT_COLOR = (255, 255, 255)

FONT = pygame.font.SysFont("arial", 30)
BIG_FONT = pygame.font.SysFont("arial", 60)

# 物理参数
GRAVITY = 0.6
JUMP_STRENGTH = -12
SPRING_STRENGTH = -18
MOVE_SPEED = 6
FRICTION = 0.85

# --- 游戏对象 ---

class Camera:
    def __init__(self):
        self.offset_y = 0
        self.max_height = 0

    def update(self, player_y):
        # 只有当玩家跳得比历史最高点还高时，镜头才上移
        if player_y < self.max_height:
            self.max_height = player_y
            target_offset = -player_y + HEIGHT // 3
            self.offset_y += (target_offset - self.offset_y) * 0.1

class Platform:
    def __init__(self, x, y, w, ptype='normal'):
        self.rect = pygame.Rect(x, y, w, 15)
        self.type = ptype
        self.alive = True
        self.vel_x = 0
        if ptype == 'moving':
            self.vel_x = random.choice([-2, 2])

    def update(self):
        if self.type == 'moving':
            self.rect.x += self.vel_x
            if self.rect.left < 0 or self.rect.right > WIDTH:
                self.vel_x *= -1

    def draw(self, surface, cam_y):
        if not self.alive: return
        color_map = {
            'normal': PLAT_NORMAL,
            'spring': PLAT_SPRING,
            'fragile': PLAT_FRAGILE,
            'moving': PLAT_MOVING
        }
        pygame.draw.rect(surface, color_map.get(self.type, PLAT_NORMAL), 
                         self.rect.move(0, cam_y))

class Player:
    def __init__(self, x, y):
        self.rect = pygame.Rect(x, y, 30, 30)
        self.vel_x = 0
        self.vel_y = 0
        self.on_ground = False
        self.alive = True
        self.score = 0

    def jump(self):
        if self.on_ground and self.alive:
            self.vel_y = JUMP_STRENGTH
            self.on_ground = False

    def update(self, platforms):
        if not self.alive: 
            self.vel_y += GRAVITY
            self.rect.y += self.vel_y
            return

        # 输入
        keys = pygame.key.get_pressed()
        if keys[pygame.K_LEFT]: self.vel_x -= 1.2
        if keys[pygame.K_RIGHT]: self.vel_x += 1.2
        
        # 摩擦力 & 限速
        self.vel_x *= FRICTION
        if abs(self.vel_x) > MOVE_SPEED: self.vel_x = MOVE_SPEED if self.vel_x > 0 else -MOVE_SPEED
        if abs(self.vel_x) < 0.1: self.vel_x = 0

        # 重力
        self.vel_y += GRAVITY
        if self.vel_y > 15: self.vel_y = 15

        # 水平移动 & 边界
        self.rect.x += self.vel_x
        if self.rect.left < 0: self.rect.left = 0
        if self.rect.right > WIDTH: self.rect.right = WIDTH

        # 垂直移动 & 碰撞
        self.rect.y += self.vel_y
        self.on_ground = False
        
        for p in platforms:
            if not p.alive: continue
            # 只在下落时碰撞，且脚底在平台上方
            if self.vel_y > 0 and self.rect.bottom >= p.rect.top and self.rect.bottom <= p.rect.top + 15:
                if self.rect.right > p.rect.left and self.rect.left < p.rect.right:
                    self.rect.bottom = p.rect.top
                    self.vel_y = 0
                    self.on_ground = True
                    
                    # 平台效果
                    if p.type == 'spring':
                        self.vel_y = SPRING_STRENGTH
                        self.on_ground = False
                    elif p.type == 'fragile':
                        p.alive = False
                    break

        # 死亡判定：掉出屏幕底部（相对于相机）
        # 这里简单处理：如果 y 坐标比当前最高分还低 600 像素就死
        # 实际应该用 camera.offset_y 来判断
        if self.rect.top > 600: # 临时判定，主循环会修正
            self.alive = False

    def draw(self, surface, cam_y):
        color = PLAYER_COLOR if self.alive else (150, 50, 50)
        pygame.draw.rect(surface, color, self.rect.move(0, cam_y))

# --- 关卡生成 ---
def generate_platforms(start_y, count):
    plats = []
    y = start_y
    for _ in range(count):
        x = random.randint(0, WIDTH - 80)
        w = random.randint(60, 100)
        
        # 随机类型
        r = random.random()
        ptype = 'normal'
        if r > 0.9: ptype = 'spring'
        elif r > 0.8: ptype = 'fragile'
        elif r > 0.7: ptype = 'moving'
        
        plats.append(Platform(x, y, w, ptype))
        y -= random.randint(60, 100)  # 垂直间距
    return plats

# --- 主程序 ---
def main():
    player = Player(WIDTH//2, HEIGHT - 100)
    camera = Camera()
    
    # 初始平台
    platforms = [Platform(WIDTH//2 - 50, HEIGHT - 50, 100, 'normal')]
    platforms.extend(generate_platforms(HEIGHT - 150, 50))
    
    game_over = False
    running = True
    
    while running:
        clock.tick(60)
        
        for event in pygame.event.get():
            if event.type == pygame.QUIT: running = False
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    if game_over: 
                        main(); return
                    else: 
                        player.jump()

        if not game_over:
            player.update(platforms)
            for p in platforms: p.update()
            
            # 更新相机
            camera.update(player.rect.y)
            
            # 真正的死亡判定：玩家位置 > 相机底部
            if player.rect.top > camera.offset_y + HEIGHT + 100:
                game_over = True
                player.alive = False

            # 计算分数（高度）
            current_height = int((-player.rect.y + HEIGHT) / 10)
            if current_height > player.score:
                player.score = current_height

            # 动态生成新平台（当玩家接近顶部时）
            if player.rect.y < camera.offset_y + 200:
                platforms.extend(generate_platforms(camera.offset_y - 200, 20))

            # 清理屏幕下方的旧平台
            platforms = [p for p in platforms if p.rect.y < camera.offset_y + HEIGHT + 200]

        # --- 绘图 ---
        screen.fill(BG_COLOR)
        
        # 绘制平台
        for p in platforms: p.draw(screen, camera.offset_y)
        player.draw(screen, camera.offset_y)

        # UI
        score_txt = FONT.render(f"Height: {player.score}m", True, TEXT_COLOR)
        screen.blit(score_txt, (10, 10))

        if game_over:
            over_txt = BIG_FONT.render("GAME OVER", True, (255, 50, 50))
            sub_txt = FONT.render("Press SPACE to Retry", True, TEXT_COLOR)
            screen.blit(over_txt, over_txt.get_rect(center=(WIDTH//2, HEIGHT//2 - 30)))
            screen.blit(sub_txt, sub_txt.get_rect(center=(WIDTH//2, HEIGHT//2 + 30)))

        pygame.display.flip()

    pygame.quit()

if __name__ == "__main__":
    main()