import pygame
import random
import sys

# ====================== 初始化 ======================
pygame.init()
WIDTH, HEIGHT = 480, 700
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("男人上一百层【升级版】")
clock = pygame.time.Clock()

# 颜色常量
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 60, 60)
GREEN = (40, 180, 40)
BLUE = (30, 140, 255)
YELLOW = (255, 220, 0)    # 弹簧平台颜色
PURPLE = (170, 80, 220)   # 移动平台颜色

# ====================== 游戏参数 ======================
player_w = 30
player_h = 40
player_x = WIDTH // 2 - player_w // 2
player_y = HEIGHT - 120
speed_x = 6
gravity = 0.6
jump_power = -16
spring_jump_power = -26  # 弹簧更高弹跳
vel_y = 0

# 平台类型定义
# 平台结构 [x, y, w, h, type, move_dir, move_speed]
# type: 0普通  1移动平台  2弹簧平台
plat_w_min = 60
plat_w_max = 120
plat_h = 16

# 加载玩家图片
try:
    player_img = pygame.image.load("res/player.png").convert_alpha()
    player_img = pygame.transform.scale(player_img, (player_w, player_h))
    use_image = True
except Exception:
    use_image = False
    print("未找到角色图片，使用矩形代替，请在res文件夹放入player.png")

platform_list = []
score = 0
font = pygame.font.SysFont(None, 36)
game_over = False

# ====================== 函数 ======================
def create_platform(y_start, count):
    plats = []
    y = y_start
    for _ in range(count):
        w = random.randint(plat_w_min, plat_w_max)
        x = random.randint(0, WIDTH - w)
        # 随机平台种类
        r = random.random()
        if r < 0.65:
            p_type = 0  # 普通
        elif r < 0.85:
            p_type = 1  # 移动平台
        else:
            p_type = 2  # 弹簧平台
        move_dir = 1
        move_speed = random.uniform(1.2, 2.5) if p_type == 1 else 0
        plats.append([x, y, w, plat_h, p_type, move_dir, move_speed])
        y -= random.randint(70, 130)
    return plats

platform_list = create_platform(HEIGHT - 60, 12)

# ====================== 主循环 ======================
while True:
    screen.fill((25, 25, 40))
    # 事件监听
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        if event.type == pygame.KEYDOWN:
            if game_over and event.key == pygame.K_SPACE:
                # 游戏重置
                player_x = WIDTH // 2 - player_w // 2
                player_y = HEIGHT - 120
                vel_y = 0
                score = 0
                platform_list = create_platform(HEIGHT - 60, 12)
                game_over = False

    if not game_over:
        # 左右移动
        keys = pygame.key.get_pressed()
        if keys[pygame.K_LEFT]:
            player_x -= speed_x
        if keys[pygame.K_RIGHT]:
            player_x += speed_x

        # 屏幕左右循环穿墙
        if player_x > WIDTH:
            player_x = -player_w
        if player_x < -player_w:
            player_x = WIDTH

        # 重力模拟
        vel_y += gravity
        player_y += vel_y

        # 更新移动平台位置
        for plat in platform_list:
            px, py, pw, ph, ptype, move_dir, move_sp = plat
            if ptype == 1:
                plat[0] += move_dir * move_sp
                # 碰到边界反弹
                if plat[0] <= 0 or plat[0] + pw >= WIDTH:
                    plat[5] *= -1

        # 碰撞检测
        for plat in platform_list:
            px, py, pw, ph, ptype, _, _ = plat
            # 只有下落时才能踩平台
            if vel_y > 0:
                if (player_x + player_w > px and player_x < px + pw and
                    player_y + player_h > py and player_y + player_h < py + ph + vel_y):
                    player_y = py - player_h
                    # 判断平台类型，设置弹跳力度
                    if ptype == 2:
                        vel_y = spring_jump_power
                    else:
                        vel_y = jump_power

        # 镜头滚动逻辑
        scroll_threshold = HEIGHT * 0.35
        if player_y < scroll_threshold:
            offset = scroll_threshold - player_y
            player_y = scroll_threshold
            # 所有平台向下移动
            for p in platform_list:
                p[1] += offset
            score += int(offset)

        # 清理下方超出屏幕平台，持续生成上方新平台
        if platform_list:
            new_top_y = min(p[1] for p in platform_list)
        # 删除屏幕下方平台
        platform_list = [p for p in platform_list if p[1] < HEIGHT + 20]
        # 不断生成顶部平台
        while new_top_y > -80:
            w = random.randint(plat_w_min, plat_w_max)
            x = random.randint(0, WIDTH - w)
            r = random.random()
            if r < 0.65:
                p_type = 0
            elif r < 0.85:
                p_type = 1
            else:
                p_type = 2
            move_dir = 1
            move_speed = random.uniform(1.2, 2.8) if p_type == 1 else 0
            new_top_y -= random.randint(70, 130)
            platform_list.append([x, new_top_y, w, plat_h, p_type, move_dir, move_speed])

        # 掉落判定
        if player_y > HEIGHT:
            game_over = True

    # ====================== 绘制 ======================
    for p in platform_list:
        px, py, pw, ph, ptype, _, _ = p
        if ptype == 0:
            color = GREEN
        elif ptype == 1:
            color = PURPLE
        else:
            color = YELLOW
        pygame.draw.rect(screen, color, (px, py, pw, ph))

    # 绘制玩家
    if use_image:
        screen.blit(player_img, (player_x, player_y))
    else:
        pygame.draw.rect(screen, RED, (player_x, player_y, player_w, player_h))

    # 分数文本
    text = font.render(f"高度: {score}", True, WHITE)
    screen.blit(text, (10, 10))

    # 图例提示
    tip_text = font.render("绿=普通 |紫=移动 |黄=弹簧", True, WHITE)
    screen.blit(tip_text, (10, 45))

    if game_over:
        over_text = font.render("游戏结束！按空格重新开始", True, WHITE)
        screen.blit(over_text, (WIDTH//2 - over_text.get_width()//2, HEIGHT//2))

    pygame.display.flip()
    clock.tick(60)