import pygame
import random
import math
import sys

# 初始化
pygame.init()
pygame.mixer.init()

WIDTH, HEIGHT = 400, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("是男人上一百层")
clock = pygame.time.Clock()
FPS = 60

# 颜色
BLACK = (20, 20, 20)
WHITE = (255, 255, 255)
RED = (255, 60, 60)
GREEN = (40, 220, 40)    # 普通
YELLOW = (255, 220, 0)   # 弹簧
GRAY = (120, 120, 120)   # 易碎
BLUE = (80, 180, 255)

# 中文字体
try:
    font_large = pygame.font.SysFont("Microsoft YaHei", 42)
    font_mid = pygame.font.SysFont("Microsoft YaHei", 26)
    font_sml = pygame.font.SysFont("Microsoft YaHei", 18)
except:
    font_large = pygame.font.SysFont("simhei", 42)
    font_mid = pygame.font.SysFont("simhei", 26)
    font_sml = pygame.font.SysFont("simhei", 18)

# 简易音效
def make_sound(freq, dur):
    samples = []
    for i in range(int(44100 * dur)):
        val = 127 + 127 * math.sin(2 * math.pi * freq * i / 44100)
        samples.append(int(val))
    sound = pygame.mixer.Sound(buffer=bytes(samples))
    sound.set_volume(0.12)
    return sound

jump_snd = make_sound(480, 0.07)
spring_snd = make_sound(700, 0.1)
break_snd = make_sound(200, 0.1)

# 玩家
class Player(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.Surface((22, 22))
        self.image.fill(RED)
        self.rect = self.image.get_rect()
        self.rect.centerx = WIDTH // 2
        self.rect.bottom = HEIGHT - 10

        self.vx = 0
        self.vy = 0
        self.gravity = 0.4
        self.jump_pow = -13
        self.spring_pow = -22

    def update(self):
        self.vy += self.gravity
        self.rect.x += self.vx
        self.rect.y += self.vy

        if self.rect.left > WIDTH:
            self.rect.left = 0
        if self.rect.right < 0:
            self.rect.right = WIDTH

# 平台
class Platform(pygame.sprite.Sprite):
    def __init__(self, x, y, w, ptype=0):
        super().__init__()
        self.type = ptype
        self.image = pygame.Surface((w, 12))
        if self.type == 0:
            self.image.fill(GREEN)
        elif self.type == 1:
            self.image.fill(YELLOW)
        else:
            self.image.fill(GRAY)
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.break_timer = 0
        self.breaking = False
        self.scored = False  # 标记是否已经算过分数

# 生成少量平台 + 大间距
def create_fixed_platforms():
    group = pygame.sprite.Group()
    # 底部安全大平台
    group.add(Platform(WIDTH//2 - 100, HEIGHT - 20, 200, 0))
    y = HEIGHT - 80
    # 初始少量平台
    for _ in range(9):
        w = random.randint(60, 100)
        x = random.randint(20, WIDTH - w - 20)
        r = random.random()
        t = 0 if r < 0.65 else 1 if r < 0.88 else 2
        group.add(Platform(x, y, w, t))
        y -= 75
    return group

def draw_txt(text, font, color, cx, cy):
    surf = font.render(text, True, color)
    rect = surf.get_rect(center=(cx, cy))
    screen.blit(surf, rect)

# 开始界面
def start_ui():
    while True:
        screen.fill(BLACK)
        draw_txt("是男人上一百层", font_large, RED, WIDTH//2, 180)
        draw_txt("← → 左右移动", font_mid, WHITE, WIDTH//2, 280)
        draw_txt("绿色=普通 黄色=弹簧 灰色=易碎", font_sml, WHITE, WIDTH//2, 330)
        draw_txt("按空格键开始游戏", font_mid, BLUE, WIDTH//2, 420)
        pygame.display.flip()
        for e in pygame.event.get():
            if e.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if e.type == pygame.KEYUP and e.key == pygame.K_SPACE:
                return

# 结束界面
def over_ui(score):
    while True:
        screen.fill(BLACK)
        draw_txt("游戏结束", font_large, RED, WIDTH//2, 200)
        draw_txt(f"到达层数：{score}", font_mid, WHITE, WIDTH//2, 290)
        draw_txt("按空格重新开始", font_sml, BLUE, WIDTH//2, 380)
        pygame.display.flip()
        for e in pygame.event.get():
            if e.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if e.type == pygame.KEYUP and e.key == pygame.K_SPACE:
                return

# 主游戏
def game():
    player = Player()
    all_sp = pygame.sprite.Group(player)
    plats = create_fixed_platforms()
    all_sp.add(plats)
    floor = 0   # 层数

    while True:
        clock.tick(FPS)
        for e in pygame.event.get():
            if e.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

        # 左右移动
        key = pygame.key.get_pressed()
        player.vx = -7 if key[pygame.K_LEFT] else 7 if key[pygame.K_RIGHT] else 0

        player.update()

        # 踩踏平台 触发跳跃 + 一层一分
        hits = pygame.sprite.spritecollide(player, plats, False)
        for p in hits:
            if player.vy > 0 and player.rect.bottom <= p.rect.top + 10:
                player.rect.bottom = p.rect.top
                
                # 每踩一个新平台 只加一层
                if not p.scored:
                    floor += 1
                    p.scored = True

                if p.type == 0:
                    player.vy = player.jump_pow
                    jump_snd.play()
                elif p.type == 1:
                    player.vy = player.spring_pow
                    spring_snd.play()
                elif p.type == 2 and not p.breaking:
                    p.breaking = True
                    break_snd.play()

        # 易碎平台
        for p in plats:
            if p.breaking:
                p.break_timer += 1
                if p.break_timer > 25:
                    p.kill()

        # 镜头上移
        if player.rect.top <= HEIGHT // 3:
            offset = abs(player.vy)
            player.rect.y += offset
            for p in plats:
                p.rect.y += offset
                if p.rect.top > HEIGHT:
                    p.kill()
                    # 顶部生成新平台
                    w = random.randint(60, 100)
                    x = random.randint(20, WIDTH - w - 20)
                    r = random.random()
                    t = 0 if r < 0.65 else 1 if r < 0.88 else 2
                    np = Platform(x, random.randint(-90, -40), w, t)
                    plats.add(np)
                    all_sp.add(np)

        # 掉落死亡
        if player.rect.top > HEIGHT:
            return floor

        # 绘制
        screen.fill(BLACK)
        all_sp.draw(screen)
        draw_txt(f"层数：{floor}", font_sml, WHITE, 60, 20)
        pygame.display.flip()

if __name__ == "__main__":
    while True:
        start_ui()
        res = game()
        over_ui(res)