import pygame
import sys
import random
import math
import os

# 初始化 Pygame
pygame.init()

# 屏幕尺寸
WIDTH, HEIGHT = 480, 800
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("跳一跳")

# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
LIGHT_BLUE = (173, 216, 230)
PLATFORM_COLOR = (100, 200, 100)
PLATFORM_CENTER = (255, 215, 0)  # 平台中心金色圆点

# 游戏参数
PLAYER_RADIUS = 20
PLAYER_COLOR = (50, 50, 50)
PLATFORM_WIDTH = 120
PLATFORM_HEIGHT = 20
CENTER_RADIUS = 10
GRAVITY = 0.5
JUMP_POWER_FACTOR = 0.8

# 获取一个可用的中文字体（直接加载文件，避免触发系统字体扫描的 bug）
def get_font(size):
    # 常见的 Windows 中文字体文件路径
    font_paths = [
        "C:/Windows/Fonts/simhei.ttf",      # 黑体
        "C:/Windows/Fonts/simsun.ttc",      # 宋体
        "C:/Windows/Fonts/msyh.ttc",        # 微软雅黑
        "C:/Windows/Fonts/msyhbd.ttc",      # 微软雅黑粗体
    ]
    for path in font_paths:
        if os.path.exists(path):
            try:
                return pygame.font.Font(path, size)
            except:
                continue
    # 如果都找不到，使用默认字体（可能无法显示中文，但游戏逻辑正常）
    return pygame.font.Font(None, size)

# 游戏状态
class Game:
    def __init__(self):
        self.reset()

    def reset(self):
        # 当前平台（棋子站立的平台）
        self.current_platform = pygame.Rect(
            WIDTH//2 - PLATFORM_WIDTH//2,
            HEIGHT - 100,
            PLATFORM_WIDTH,
            PLATFORM_HEIGHT
        )
        # 下一个目标平台
        self.next_platform = self.generate_next_platform()
        # 棋子位置（初始站在当前平台中心上方）
        self.player_x = self.current_platform.centerx
        self.player_y = self.current_platform.top - PLAYER_RADIUS
        self.player_vx = 0
        self.player_vy = 0
        self.is_jumping = False
        self.is_charging = False
        self.charge_time = 0
        self.score = 0
        self.game_over = False
        # 使用安全的字体获取方式
        self.font = get_font(30)

    def generate_next_platform(self):
        """随机生成下一个平台，方向左右随机，距离也随机"""
        direction = random.choice([-1, 1])
        distance_x = random.randint(100, 200) * direction
        distance_y = random.randint(-30, 30)

        cx = self.current_platform.centerx + distance_x
        cy = self.current_platform.top + distance_y

        cx = max(PLATFORM_WIDTH//2 + 20, min(WIDTH - PLATFORM_WIDTH//2 - 20, cx))
        cy = max(100, min(HEIGHT - 100, cy))

        return pygame.Rect(
            cx - PLATFORM_WIDTH//2,
            cy,
            PLATFORM_WIDTH,
            PLATFORM_HEIGHT
        )

    def update(self):
        if self.game_over:
            return

        if self.is_jumping:
            self.player_x += self.player_vx
            self.player_y += self.player_vy
            self.player_vy += GRAVITY

            if self.player_vy > 0 and self.check_landing():
                self.calculate_score()
                self.current_platform = self.next_platform
                self.next_platform = self.generate_next_platform()
                self.player_x = self.current_platform.centerx
                self.player_y = self.current_platform.top - PLAYER_RADIUS
                self.player_vx = 0
                self.player_vy = 0
                self.is_jumping = False

            if self.player_y > HEIGHT + 50 or self.player_x < -50 or self.player_x > WIDTH + 50:
                self.game_over = True

    def check_landing(self):
        platform = self.next_platform
        if platform.left <= self.player_x <= platform.right:
            if self.player_y + PLAYER_RADIUS >= platform.top and self.player_vy > 0:
                self.player_y = platform.top - PLAYER_RADIUS
                return True
        return False

    def calculate_score(self):
        center_x = self.next_platform.centerx
        distance = abs(self.player_x - center_x)
        if distance <= CENTER_RADIUS:
            self.score += 2
        else:
            self.score += 1

    def start_charge(self):
        if not self.is_jumping and not self.game_over:
            self.is_charging = True
            self.charge_time = 0

    def stop_charge(self):
        if self.is_charging and not self.is_jumping and not self.game_over:
            self.is_charging = False
            dx = self.next_platform.centerx - self.player_x
            dy = self.next_platform.top - self.player_y
            distance = math.hypot(dx, dy)
            if distance == 0:
                distance = 1
            dir_x = dx / distance
            dir_y = dy / distance
            power = self.charge_time * JUMP_POWER_FACTOR
            self.player_vx = dir_x * power
            self.player_vy = dir_y * power
            self.is_jumping = True

    def draw(self):
        screen.fill(LIGHT_BLUE)

        pygame.draw.rect(screen, PLATFORM_COLOR, self.current_platform)
        pygame.draw.rect(screen, PLATFORM_COLOR, self.next_platform)

        pygame.draw.circle(screen, PLATFORM_CENTER,
                           (self.current_platform.centerx, self.current_platform.centery),
                           CENTER_RADIUS)
        pygame.draw.circle(screen, PLATFORM_CENTER,
                           (self.next_platform.centerx, self.next_platform.centery),
                           CENTER_RADIUS)

        pygame.draw.circle(screen, PLAYER_COLOR,
                           (int(self.player_x), int(self.player_y)), PLAYER_RADIUS)

        if self.is_charging:
            bar_length = min(200, self.charge_time * 2)
            bar_rect = pygame.Rect(20, 20, bar_length, 20)
            pygame.draw.rect(screen, (255, 100, 100), bar_rect)
            pygame.draw.rect(screen, BLACK, (20, 20, 200, 20), 2)

        score_text = self.font.render(f"分数: {self.score}", True, BLACK)
        screen.blit(score_text, (20, 60))

        if self.game_over:
            over_text = self.font.render("游戏结束! 按R重新开始", True, (255, 0, 0))
            screen.blit(over_text, (WIDTH//2 - over_text.get_width()//2, HEIGHT//2))

        pygame.display.flip()

def main():
    clock = pygame.time.Clock()
    game = Game()

    while True:
        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:
                    game.start_charge()
                if event.key == pygame.K_r and game.game_over:
                    game.reset()

            if event.type == pygame.KEYUP:
                if event.key == pygame.K_SPACE:
                    game.stop_charge()

            if event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1:
                    game.start_charge()
            if event.type == pygame.MOUSEBUTTONUP:
                if event.button == 1:
                    game.stop_charge()

        if game.is_charging:
            game.charge_time += 1

        game.update()
        game.draw()
        clock.tick(60)

if __name__ == "__main__":
    main()