import pygame
import random
import sys
import os
import time
from typing import List, Tuple

# 初始化pygame
pygame.init()

# 游戏常量
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
FPS = 60
GRAVITY = 1
JUMP_FORCE = -20
GAME_SPEED = 5
OBSTACLE_SPEED_INCREASE = 0.002

# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 50, 50)
GREEN = (50, 255, 50)
BLUE = (50, 150, 255)
YELLOW = (255, 255, 50)
PURPLE = (180, 50, 230)
SKY_BLUE = (135, 206, 235)
GROUND_COLOR = (100, 70, 30)
GRASS_COLOR = (50, 180, 50)
CLOUD_COLOR = (240, 240, 240)
ORANGE = (255, 165, 0)

# 字体处理
def load_font(size):
    """尝试加载中文字体，如果失败则使用默认字体"""
    font_paths = [
        "C:/Windows/Fonts/simhei.ttf",  # Windows 黑体
        "C:/Windows/Fonts/msyh.ttc",    # Windows 微软雅黑
        "C:/Windows/Fonts/simsun.ttc",   # Windows 宋体
        "/System/Library/Fonts/PingFang.ttc",  # Mac
        "/usr/share/fonts/truetype/wqy/wqy-microhei.ttc",  # Linux
    ]
    
    for font_path in font_paths:
        if os.path.exists(font_path):
            try:
                return pygame.font.Font(font_path, size)
            except:
                continue
    
    # 如果都找不到，使用默认字体
    print("警告: 未找到中文字体，使用默认字体，中文可能显示为方框")
    return pygame.font.Font(None, size)

class Player:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.width = 40
        self.height = 60
        self.vel_y = 0
        self.jumping = False
        self.ducking = False
        self.score = 0
        self.color = BLUE
        self.animation_timer = 0
        
    def jump(self):
        if not self.jumping:
            self.vel_y = JUMP_FORCE
            self.jumping = True
            
    def duck(self):
        if not self.jumping and not self.ducking:
            self.ducking = True
            self.height = 30
            self.y += 30  # 降低高度
            
    def stand_up(self):
        if self.ducking:
            self.ducking = False
            self.y -= 30
            self.height = 60
            
    def update(self):
        # 应用重力
        self.vel_y += GRAVITY
        self.y += self.vel_y
        
        # 防止角色掉出屏幕
        if self.y > SCREEN_HEIGHT - 100 - self.height:
            self.y = SCREEN_HEIGHT - 100 - self.height
            self.jumping = False
            self.vel_y = 0
            
        # 动画计时器
        self.animation_timer = (self.animation_timer + 1) % 10
            
    def draw(self, screen):
        # 绘制角色
        pygame.draw.rect(screen, self.color, (self.x, self.y, self.width, self.height), 0, 10)
        
        # 绘制眼睛
        eye_y = self.y + 15
        if self.ducking:
            eye_y = self.y + 5
            
        pygame.draw.circle(screen, WHITE, (self.x + 10, eye_y), 8)
        pygame.draw.circle(screen, WHITE, (self.x + 30, eye_y), 8)
        pygame.draw.circle(screen, BLACK, (self.x + 10, eye_y), 4)
        pygame.draw.circle(screen, BLACK, (self.x + 30, eye_y), 4)
        
        # 绘制嘴巴
        mouth_y = eye_y + 20
        if self.ducking:
            mouth_y = eye_y + 10
        pygame.draw.arc(screen, RED, (self.x + 10, mouth_y - 5, 20, 10), 0, 3.14, 3)
        
    def get_rect(self):
        return pygame.Rect(self.x, self.y, self.width, self.height)

class Obstacle:
    def __init__(self, x, y, obstacle_type):
        self.x = x
        self.y = y
        self.type = obstacle_type
        self.speed = GAME_SPEED
        
        if obstacle_type == "block":
            self.width = 40
            self.height = 40
            self.color = RED
        elif obstacle_type == "gap":
            self.width = 100
            self.height = 20
            self.color = GROUND_COLOR
        elif obstacle_type == "bird":
            self.width = 60
            self.height = 30
            self.color = YELLOW
            
    def update(self, game_speed):
        self.x -= game_speed
        self.speed = game_speed
        
    def draw(self, screen):
        if self.type == "block":
            pygame.draw.rect(screen, self.color, (self.x, self.y, self.width, self.height), 0, 5)
            # 绘制纹理
            pygame.draw.line(screen, (200, 0, 0), (self.x + 5, self.y + 5), 
                           (self.x + 35, self.y + 5), 2)
            pygame.draw.line(screen, (200, 0, 0), (self.x + 5, self.y + 15), 
                           (self.x + 35, self.y + 15), 2)
            pygame.draw.line(screen, (200, 0, 0), (self.x + 5, self.y + 25), 
                           (self.x + 35, self.y + 25), 2)
            pygame.draw.line(screen, (200, 0, 0), (self.x + 5, self.y + 35), 
                           (self.x + 35, self.y + 35), 2)
            
        elif self.type == "gap":
            # 绘制缺口
            pygame.draw.rect(screen, SKY_BLUE, (self.x, self.y, self.width, self.height))
            
        elif self.type == "bird":
            # 绘制鸟
            pygame.draw.ellipse(screen, self.color, (self.x, self.y, self.width, self.height))
            # 翅膀
            pygame.draw.ellipse(screen, (200, 200, 0), (self.x - 5, self.y + 5, 20, 10))
            pygame.draw.ellipse(screen, (200, 200, 0), (self.x + 45, self.y + 5, 20, 10))
            # 眼睛
            pygame.draw.circle(screen, BLACK, (self.x + 15, self.y + 10), 3)
            pygame.draw.circle(screen, BLACK, (self.x + 45, self.y + 10), 3)
            # 喙
            pygame.draw.polygon(screen, ORANGE, [
                (self.x + 60, self.y + 15),
                (self.x + 70, self.y + 15),
                (self.x + 65, self.y + 20)
            ])
            
    def get_rect(self):
        if self.type == "gap":
            # 缺口不需要碰撞检测
            return pygame.Rect(0, 0, 0, 0)
        return pygame.Rect(self.x, self.y, self.width, self.height)

class Cloud:
    def __init__(self):
        self.x = SCREEN_WIDTH
        self.y = random.randint(50, 200)
        self.speed = random.randint(1, 3)
        self.size = random.randint(30, 60)
        
    def update(self, game_speed):
        self.x -= self.speed
        
    def draw(self, screen):
        # 绘制云朵
        pygame.draw.circle(screen, CLOUD_COLOR, (int(self.x), int(self.y)), self.size)
        pygame.draw.circle(screen, CLOUD_COLOR, (int(self.x) + self.size//2, int(self.y) - 10), self.size//1.5)
        pygame.draw.circle(screen, CLOUD_COLOR, (int(self.x) + self.size, int(self.y)), self.size)
        
    def is_offscreen(self):
        return self.x < -self.size * 2

class Coin:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.radius = 15
        self.collected = False
        self.animation_offset = 0
        
    def update(self, game_speed):
        self.x -= game_speed
        self.animation_offset = (self.animation_offset + 5) % 360
        
    def draw(self, screen):
        if not self.collected:
            # 旋转动画
            angle = self.animation_offset
            bounce = 5 * abs(pygame.math.Vector2(1, 0).rotate(angle).y)
            
            # 绘制金币
            pygame.draw.circle(screen, YELLOW, (int(self.x), int(self.y + bounce)), self.radius)
            pygame.draw.circle(screen, (200, 200, 0), (int(self.x), int(self.y + bounce)), self.radius, 2)
            
            # 绘制$符号
            font = load_font(30)
            try:
                text = font.render("$", True, (100, 100, 0))
            except:
                font = pygame.font.Font(None, 30)
                text = font.render("$", True, (100, 100, 0))
            text_rect = text.get_rect(center=(int(self.x), int(self.y + bounce)))
            screen.blit(text, text_rect)
            
    def get_rect(self):
        return pygame.Rect(self.x - self.radius, self.y - self.radius, 
                          self.radius * 2, self.radius * 2)
        
    def is_offscreen(self):
        return self.x < -self.radius

class Game:
    def __init__(self):
        self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
        pygame.display.set_caption("跑酷游戏 v1.0")
        self.clock = pygame.time.Clock()
        
        # 加载字体
        self.font = load_font(36)
        self.big_font = load_font(72)
        self.small_font = load_font(24)
        
        self.running = True
        self.game_active = False
        self.game_over = False
        self.score = 0
        self.high_score = 0
        self.game_speed = GAME_SPEED
        self.obstacle_timer = 0
        self.coin_timer = 0
        
        # 游戏对象
        self.player = Player(100, SCREEN_HEIGHT - 200)
        self.obstacles: List[Obstacle] = []
        self.coins: List[Coin] = []
        self.clouds: List[Cloud] = []
        
    def start_game(self):
        """开始新游戏"""
        self.game_active = True
        self.game_over = False
        self.score = 0
        self.game_speed = GAME_SPEED
        self.player = Player(100, SCREEN_HEIGHT - 200)
        self.obstacles = []
        self.coins = []
        self.clouds = []
        self.obstacle_timer = 0
        self.coin_timer = 0
        
    def spawn_obstacle(self):
        """生成障碍物"""
        obstacle_types = ["block", "block", "gap", "bird"]
        obstacle_type = random.choice(obstacle_types)
        
        if obstacle_type == "block":
            y = SCREEN_HEIGHT - 100 - 40
        elif obstacle_type == "gap":
            y = SCREEN_HEIGHT - 100
        elif obstacle_type == "bird":
            y = random.randint(SCREEN_HEIGHT - 300, SCREEN_HEIGHT - 150)
            
        obstacle = Obstacle(SCREEN_WIDTH, y, obstacle_type)
        self.obstacles.append(obstacle)
        
    def spawn_coin(self):
        """生成金币"""
        x = SCREEN_WIDTH
        y = random.randint(100, SCREEN_HEIGHT - 150)
        coin = Coin(x, y)
        self.coins.append(coin)
        
    def spawn_cloud(self):
        """生成云朵"""
        if random.random() < 0.02:  # 2%的几率生成云
            cloud = Cloud()
            self.clouds.append(cloud)
            
    def handle_events(self):
        """处理游戏事件"""
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.running = False
                
            elif event.type == pygame.KEYDOWN:
                if not self.game_active:
                    if event.key == pygame.K_SPACE:
                        self.start_game()
                    elif event.key == pygame.K_ESCAPE:
                        self.running = False
                else:
                    if event.key == pygame.K_SPACE or event.key == pygame.K_UP:
                        self.player.jump()
                    elif event.key == pygame.K_DOWN:
                        self.player.duck()
                    elif event.key == pygame.K_ESCAPE:
                        self.game_active = False
                        
            elif event.type == pygame.KEYUP:
                if event.key == pygame.K_DOWN:
                    self.player.stand_up()
                    
    def update(self):
        """更新游戏状态"""
        if not self.game_active or self.game_over:
            return
            
        # 更新角色
        self.player.update()
        
        # 更新游戏速度
        self.game_speed += OBSTACLE_SPEED_INCREASE
        self.score += 0.1  # 根据时间加分
        
        # 生成障碍物
        self.obstacle_timer += 1
        if self.obstacle_timer > 60:  # 每秒生成一个障碍物
            if random.random() < 0.7:  # 70%几率生成障碍
                self.spawn_obstacle()
            self.obstacle_timer = 0
            
        # 生成金币
        self.coin_timer += 1
        if self.coin_timer > 30:  # 每0.5秒可能生成金币
            if random.random() < 0.3:  # 30%几率生成金币
                self.spawn_coin()
            self.coin_timer = 0
            
        # 生成云朵
        self.spawn_cloud()
        
        # 更新障碍物
        for obstacle in self.obstacles[:]:
            obstacle.update(self.game_speed)
            if obstacle.x < -obstacle.width:
                self.obstacles.remove(obstacle)
                
        # 更新金币
        for coin in self.coins[:]:
            coin.update(self.game_speed)
            if coin.is_offscreen():
                self.coins.remove(coin)
                
        # 更新云朵
        for cloud in self.clouds[:]:
            cloud.update(self.game_speed)
            if cloud.is_offscreen():
                self.clouds.remove(cloud)
                
        # 碰撞检测 - 障碍物
        player_rect = self.player.get_rect()
        for obstacle in self.obstacles:
            obstacle_rect = obstacle.get_rect()
            if obstacle_rect.width > 0 and player_rect.colliderect(obstacle_rect):
                self.game_over = True
                if self.score > self.high_score:
                    self.high_score = int(self.score)
                    
        # 碰撞检测 - 金币
        for coin in self.coins[:]:
            if not coin.collected and player_rect.colliderect(coin.get_rect()):
                coin.collected = True
                self.score += 10
                self.coins.remove(coin)
                
    def draw_background(self):
        """绘制背景"""
        # 天空
        self.screen.fill(SKY_BLUE)
        
        # 云朵
        for cloud in self.clouds:
            cloud.draw(self.screen)
            
        # 远处的山
        pygame.draw.polygon(self.screen, (100, 100, 100), [
            (0, SCREEN_HEIGHT - 300),
            (200, SCREEN_HEIGHT - 400),
            (400, SCREEN_HEIGHT - 300)
        ])
        
        # 地面
        pygame.draw.rect(self.screen, GROUND_COLOR, 
                        (0, SCREEN_HEIGHT - 100, SCREEN_WIDTH, 100))
        
        # 草地
        pygame.draw.rect(self.screen, GRASS_COLOR,
                        (0, SCREEN_HEIGHT - 100, SCREEN_WIDTH, 20))
        
        # 跑道线
        for i in range(0, SCREEN_WIDTH, 100):
            pygame.draw.rect(self.screen, WHITE, 
                           (i, SCREEN_HEIGHT - 50, 50, 5))
            
    def draw_game(self):
        """绘制游戏画面"""
        # 绘制背景
        self.draw_background()
        
        # 绘制金币
        for coin in self.coins:
            coin.draw(self.screen)
            
        # 绘制障碍物
        for obstacle in self.obstacles:
            obstacle.draw(self.screen)
            
        # 绘制角色
        self.player.draw(self.screen)
        
        # 绘制分数
        score_text = self.font.render(f"分数: {int(self.score)}", True, WHITE)
        high_score_text = self.font.render(f"最高分: {int(self.high_score)}", True, WHITE)
        speed_text = self.font.render(f"速度: {self.game_speed:.1f}", True, WHITE)
        
        self.screen.blit(score_text, (10, 10))
        self.screen.blit(high_score_text, (10, 50))
        self.screen.blit(speed_text, (10, 90))
        
        # 绘制控制提示
        if int(self.score) < 100:  # 只在游戏开始时显示提示
            controls = [
                "↑/空格: 跳跃",
                "↓: 下蹲",
                "ESC: 暂停/退出"
            ]
            for i, control in enumerate(controls):
                control_text = self.font.render(control, True, WHITE)
                self.screen.blit(control_text, (SCREEN_WIDTH - 200, 10 + i * 40))
                
    def draw_start_screen(self):
        """绘制开始画面"""
        self.draw_background()
        
        # 绘制标题
        title_text = "跑酷游戏"
        try:
            title = self.big_font.render(title_text, True, YELLOW)
            title_shadow = self.big_font.render(title_text, True, BLACK)
        except:
            # 如果字体不支持中文，使用简单图形
            title = pygame.font.Font(None, 72).render("Parkour Game", True, YELLOW)
            title_shadow = pygame.font.Font(None, 72).render("Parkour Game", True, BLACK)
        
        title_rect = title.get_rect(center=(SCREEN_WIDTH//2 + 3, SCREEN_HEIGHT//3 - 100 + 3))
        self.screen.blit(title_shadow, title_rect)
        
        title_rect = title.get_rect(center=(SCREEN_WIDTH//2, SCREEN_HEIGHT//3 - 100))
        self.screen.blit(title, title_rect)
        
        # 绘制开始提示
        start_text = "按 空格键 开始游戏"
        try:
            start_render = self.font.render(start_text, True, WHITE)
        except:
            start_render = pygame.font.Font(None, 36).render("Press SPACE to start", True, WHITE)
        start_rect = start_render.get_rect(center=(SCREEN_WIDTH//2, SCREEN_HEIGHT//2))
        self.screen.blit(start_render, start_rect)
        
        # 绘制控制说明
        controls = [
            "游戏控制:",
            "空格键 或 ↑  - 跳跃",
            "↓ 键 - 下蹲躲避",
            "ESC 键 - 暂停/返回"
        ]
        
        for i, control in enumerate(controls):
            try:
                control_render = self.font.render(control, True, GREEN if i == 0 else WHITE)
            except:
                control_render = pygame.font.Font(None, 36).render(
                    ["Controls:", "SPACE or UP - Jump", "DOWN - Duck", "ESC - Pause/Back"][i], 
                    True, GREEN if i == 0 else WHITE
                )
            control_rect = control_render.get_rect(center=(SCREEN_WIDTH//2, SCREEN_HEIGHT//2 + 100 + i * 40))
            self.screen.blit(control_render, control_rect)
            
        # 绘制角色
        self.player.draw(self.screen)
        
    def draw_game_over(self):
        """绘制游戏结束画面"""
        # 半透明覆盖层
        overlay = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT), pygame.SRCALPHA)
        overlay.fill((0, 0, 0, 150))
        self.screen.blit(overlay, (0, 0))
        
        # 游戏结束文字
        try:
            game_over_text = self.big_font.render("游戏结束!", True, RED)
        except:
            game_over_text = pygame.font.Font(None, 72).render("Game Over!", True, RED)
        game_over_rect = game_over_text.get_rect(center=(SCREEN_WIDTH//2, SCREEN_HEIGHT//3))
        self.screen.blit(game_over_text, game_over_rect)
        
        # 分数
        score_text = f"本次分数: {int(self.score)}"
        high_score_text = f"最高分: {int(self.high_score)}"
        
        try:
            score_render = self.font.render(score_text, True, WHITE)
            high_score_render = self.font.render(high_score_text, True, YELLOW)
        except:
            score_render = pygame.font.Font(None, 36).render(f"Score: {int(self.score)}", True, WHITE)
            high_score_render = pygame.font.Font(None, 36).render(f"High Score: {int(self.high_score)}", True, YELLOW)
            
        score_rect = score_render.get_rect(center=(SCREEN_WIDTH//2, SCREEN_HEIGHT//2 - 50))
        high_score_rect = high_score_render.get_rect(center=(SCREEN_WIDTH//2, SCREEN_HEIGHT//2))
        
        self.screen.blit(score_render, score_rect)
        self.screen.blit(high_score_render, high_score_rect)
        
        # 重新开始提示
        restart_text = "按 空格键 重新开始"
        try:
            restart_render = self.font.render(restart_text, True, GREEN)
        except:
            restart_render = pygame.font.Font(None, 36).render("Press SPACE to restart", True, GREEN)
        restart_rect = restart_render.get_rect(center=(SCREEN_WIDTH//2, SCREEN_HEIGHT//2 + 100))
        self.screen.blit(restart_render, restart_rect)
        
    def draw(self):
        """绘制游戏画面"""
        if not self.game_active:
            self.draw_start_screen()
        else:
            self.draw_game()
            if self.game_over:
                self.draw_game_over()
                
    def run(self):
        """主游戏循环"""
        while self.running:
            self.handle_events()
            self.update()
            self.draw()
            
            # 更新显示
            pygame.display.flip()
            self.clock.tick(FPS)
            
        pygame.quit()
        sys.exit()

# 如果没有找到字体，使用备用方案
def create_fallback_fonts():
    """创建备用字体"""
    try:
        # 尝试加载系统字体
        return load_font(36), load_font(72)
    except:
        # 如果都失败，使用默认字体显示英文
        print("使用英文界面（中文字体加载失败）")
        return pygame.font.Font(None, 36), pygame.font.Font(None, 72)

# 简化版本 - 如果上述代码仍然有问题，使用这个版本
def simple_main():
    """简化版本的主函数"""
    pygame.init()
    screen = pygame.display.set_mode((800, 600))
    pygame.display.set_caption("Parkour Game - Simple Version")
    clock = pygame.time.Clock()
    
    # 使用英文界面避免字体问题
    font = pygame.font.Font(None, 36)
    big_font = pygame.font.Font(None, 72)
    
    # 简单的游戏状态
    game_active = False
    score = 0
    player_y = 400
    player_vel_y = 0
    obstacles = []
    
    # 主游戏循环
    running = True
    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    if not game_active:
                        game_active = True
                        score = 0
                        obstacles = []
                        player_y = 400
                        player_vel_y = 0
                    else:
                        player_vel_y = -15
        
        # 填充背景
        screen.fill(SKY_BLUE)
        
        if not game_active:
            # 开始画面
            title = big_font.render("Parkour Game", True, YELLOW)
            instruction = font.render("Press SPACE to start", True, WHITE)
            screen.blit(title, (250, 200))
            screen.blit(instruction, (300, 300))
        else:
            # 游戏逻辑
            # 更新玩家
            player_vel_y += 1
            player_y += player_vel_y
            if player_y > 400:
                player_y = 400
                player_vel_y = 0
            
            # 生成障碍物
            if len(obstacles) == 0 or obstacles[-1].x < 600:
                obstacles.append(pygame.Rect(800, 400, 50, 50))
            
            # 更新障碍物
            for obs in obstacles[:]:
                obs.x -= 5
                if obs.x < -50:
                    obstacles.remove(obs)
                    score += 1
            
            # 碰撞检测
            player_rect = pygame.Rect(100, player_y, 40, 60)
            for obs in obstacles:
                if player_rect.colliderect(obs):
                    game_active = False
            
            # 绘制
            # 地面
            pygame.draw.rect(screen, GROUND_COLOR, (0, 450, 800, 150))
            pygame.draw.rect(screen, GRASS_COLOR, (0, 450, 800, 20))
            
            # 障碍物
            for obs in obstacles:
                pygame.draw.rect(screen, RED, obs)
            
            # 玩家
            pygame.draw.rect(screen, BLUE, player_rect)
            
            # 分数
            score_text = font.render(f"Score: {score}", True, WHITE)
            screen.blit(score_text, (10, 10))
        
        pygame.display.flip()
        clock.tick(60)
    
    pygame.quit()

# 运行游戏
if __name__ == "__main__":
    # 检查是否安装了pygame
    try:
        import pygame
    except ImportError:
        print("请先安装pygame库: pip install pygame")
        sys.exit(1)
        
    # 尝试运行完整版本，如果出错则运行简化版本
    try:
        game = Game()
        game.run()
    except Exception as e:
        print(f"运行完整版本时出错: {e}")
        print("正在切换到简化版本...")
        simple_main()