import pygame
import random
import sys
import os

# ===================== 初始化配置 =====================
pygame.init()
# 窗口尺寸
WIDTH = 480
HEIGHT = 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("是男人就上一百层")
clock = pygame.time.Clock()
FPS = 60

# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 200, 0)
BLUE = (30, 144, 255)
GRAY = (100, 100, 100)

# ========== 修复字体加载（使用系统字体名称，不会报文件找不到）==========
try:
    # 优先微软雅黑（Windows系统自带）
    font_big = pygame.font.SysFont("microsoft yahei", 36)
    font_mid = pygame.font.SysFont("microsoft yahei", 24)
    font_small = pygame.font.SysFont("microsoft yahei", 18)
except:
    try:
        # 备选宋体
        font_big = pygame.font.SysFont("simsun", 36)
        font_mid = pygame.font.SysFont("simsun", 24)
        font_small = pygame.font.SysFont("simsun", 18)
    except:
        # 兜底默认字体，中文会显示方框，但程序不会崩溃
        font_big = pygame.font.Font(None, 36)
        font_mid = pygame.font.Font(None, 24)
        font_small = pygame.font.Font(None, 18)

# 玩家属性
player_w = 30
player_h = 40
player_x = WIDTH // 2 - player_w // 2
player_y = HEIGHT - 100
player_speed_x = 6
gravity = 0.6
jump_power = -14
vel_y = 0
on_floor = True

# 平台（阶梯）类
class Platform:
    def __init__(self, x, y, w, h):
        self.x = x
        self.y = y
        self.w = w
        self.h = h
        # 横向移动开关（部分台阶左右漂移增加难度）
        self.move = random.choice([True, False, False])
        self.move_speed = random.randint(1, 2)
        self.move_dir = random.choice([-1, 1])

    def update(self):
        if self.move:
            self.x += self.move_speed * self.move_dir
            # 碰到边界反弹
            if self.x <= 0 or self.x + self.w >= WIDTH:
                self.move_dir *= -1

    def draw(self):
        pygame.draw.rect(screen, GREEN, (self.x, self.y, self.w, self.h), border_radius=4)

# 生成初始台阶
platforms = []
# 出生落脚台
platforms.append(Platform(WIDTH//2 - 40, HEIGHT - 60, 80, 12))
# 批量生成上方台阶
for i in range(1, 20):
    plat_x = random.randint(20, WIDTH - 90)
    plat_y = HEIGHT - 60 - i * 70
    plat_w = random.randint(50, 90)
    platforms.append(Platform(plat_x, plat_y, plat_w, 12))

score = 0  # 层数分数
game_over = False
game_start = False

# ===================== 游戏主循环 =====================
while True:
    screen.fill(BLACK)
    clock.tick(FPS)

    # 事件监听
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        # 空格跳跃 / 点击开始游戏
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                if not game_start:
                    game_start = True
                if on_floor and not game_over:
                    vel_y = jump_power
                    on_floor = False
            # 游戏结束按R重新开始
            if event.key == pygame.K_r and game_over:
                # 重置所有数据
                player_x = WIDTH // 2 - player_w // 2
                player_y = HEIGHT - 100
                vel_y = 0
                on_floor = True
                score = 0
                game_over = False
                platforms.clear()
                platforms.append(Platform(WIDTH//2 - 40, HEIGHT - 60, 80, 12))
                for i in range(1, 20):
                    plat_x = random.randint(20, WIDTH - 90)
                    plat_y = HEIGHT - 60 - i * 70
                    plat_w = random.randint(50, 90)
                    platforms.append(Platform(plat_x, plat_y, plat_w, 12))

    # 开始界面
    if not game_start:
        text1 = font_big.render("是男人就上一百层", True, WHITE)
        text2 = font_mid.render("按 空格键 开始游戏", True, BLUE)
        text3 = font_small.render("← → 左右移动 | 空格跳跃 | R重新开始", True, GRAY)
        screen.blit(text1, (WIDTH//2 - text1.get_width()//2, 180))
        screen.blit(text2, (WIDTH//2 - text2.get_width()//2, 260))
        screen.blit(text3, (WIDTH//2 - text3.get_width()//2, 320))
        pygame.display.update()
        continue

    # 游戏结束界面
    if game_over:
        over_text = font_big.render(f"游戏结束！到达层数：{score}", True, RED)
        tip_text = font_mid.render("按 R 键重新挑战", True, WHITE)
        screen.blit(over_text, (WIDTH//2 - over_text.get_width()//2, 220))
        screen.blit(tip_text, (WIDTH//2 - tip_text.get_width()//2, 280))
        pygame.display.update()
        continue

    # 玩家左右移动
    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT] and player_x > 0:
        player_x -= player_speed_x
    if keys[pygame.K_RIGHT] and player_x + player_w < WIDTH:
        player_x += player_speed_x

    # 重力加速度
    vel_y += gravity
    player_y += vel_y
    on_floor = False

    # 台阶碰撞检测（踩在平台上）
    player_rect = pygame.Rect(player_x, player_y, player_w, player_h)
    for plat in platforms:
        plat_rect = pygame.Rect(plat.x, plat.y, plat.w, plat.h)
        # 下落时踩到平台
        if vel_y > 0 and player_rect.colliderect(plat_rect):
            player_y = plat.y - player_h
            vel_y = 0
            on_floor = True

    # 镜头上移：玩家爬到屏幕上半部分，画面整体上滚加分
    if player_y < HEIGHT * 0.35:
        offset = HEIGHT * 0.35 - player_y
        player_y = HEIGHT * 0.35
        for plat in platforms:
            plat.y += offset
        score += int(offset // 2)

    # 移除屏幕下方看不见的台阶，同时生成新台阶往上补充
    delete_list = []
    for index, plat in enumerate(platforms):
        plat.update()
        if plat.y > HEIGHT:
            delete_list.append(index)
    for idx in reversed(delete_list):
        del platforms[idx]
        # 在最上方生成新台阶
        max_y = min(p.y for p in platforms)
        new_x = random.randint(10, WIDTH - 90)
        new_w = random.randint(45, 95)
        platforms.append(Platform(new_x, max_y - random.randint(60, 85), new_w, 12))

    # 玩家掉落出屏幕 → 游戏结束
    if player_y > HEIGHT:
        game_over = True

    # 绘制所有台阶
    for p in platforms:
        p.draw()
    # 绘制玩家（红色方块代表人）
    pygame.draw.rect(screen, RED, (player_x, player_y, player_w, player_h), border_radius=6)
    # 绘制分数
    score_text = font_mid.render(f"层数：{score}", True, WHITE)
    screen.blit(score_text, (10, 10))
    # 一百层通关提示
    if score >= 100:
        win_text = font_big.render("恭喜！成功上100层！", True, GREEN)
        screen.blit(win_text, (WIDTH//2 - win_text.get_width()//2, HEIGHT//2))

    pygame.display.flip()