import pygame
import sys
import random
import math
import time

# 初始化pygame
pygame.init()

# 游戏窗口设置
SCREEN_WIDTH = 1000
SCREEN_HEIGHT = 600
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("极限跑酷挑战")
clock = pygame.time.Clock()
FPS = 60

# 颜色定义
SKY_COLOR = (135, 206, 235)
SUN_COLOR = (255, 255, 100)
CLOUD_COLOR = (255, 255, 255)
GROUND_COLOR = (76, 175, 80)
PLATFORM_COLOR = (121, 85, 72)
PLAYER_COLOR = (33, 150, 243)
ENEMY_COLOR = (244, 67, 54)
COIN_COLOR = (255, 193, 7)
SPRING_COLOR = (0, 188, 212)
TEXT_COLOR = (255, 255, 255)
TEXT_SHADOW = (0, 0, 0)
BUTTON_COLOR = (30, 136, 229)
BUTTON_HOVER = (66, 165, 245)
DANGER_COLOR = (255, 87, 34)
JUMP_PAD_COLOR = (156, 39, 176)
PARALLAX_FAR = (100, 181, 246)
PARALLAX_MID = (66, 165, 245)
PARALLAX_NEAR = (30, 136, 229)

# 创建字体
try:
    font_small = pygame.font.Font(None, 24)
    font_medium = pygame.font.Font(None, 36)
    font_large = pygame.font.Font(None, 48)
    font_huge = pygame.font.Font(None, 64)
except:
    font_small = pygame.font.SysFont(None, 24)
    font_medium = pygame.font.SysFont(None, 36)
    font_large = pygame.font.SysFont(None, 48)
    font_huge = pygame.font.SysFont(None, 64)

# 平台类
class Platform:
    def __init__(self, x, y, width, platform_type="normal"):
        self.x = x
        self.y = y
        self.width = width
        self.height = 20
        self.type = platform_type
        
    def get_rect(self):
        return pygame.Rect(self.x, self.y, self.width, self.height)
        
    def draw(self, surface, camera_x):
        screen_x = self.x - camera_x
        screen_y = self.y
        
        # 选择颜色
        if self.type == "danger":
            color = DANGER_COLOR
        elif self.type == "spring":
            color = SPRING_COLOR
        elif self.type == "jump_pad":
            color = JUMP_PAD_COLOR
        else:
            color = PLATFORM_COLOR
            
        pygame.draw.rect(surface, color, (screen_x, screen_y, self.width, self.height))

# 敌人
class Enemy:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.width = 30
        self.height = 40
        self.vx = random.choice([-1, 1])
        self.move_range = 100
        self.start_x = x
        
    def update(self):
        self.x += self.vx
        if abs(self.x - self.start_x) > self.move_range:
            self.vx *= -1
            
    def get_rect(self):
        return pygame.Rect(self.x, self.y, self.width, self.height)
        
    def draw(self, surface, camera_x):
        screen_x = self.x - camera_x
        screen_y = self.y
        
        pygame.draw.rect(surface, ENEMY_COLOR, (screen_x, screen_y, self.width, self.height))

# 金币
class Coin:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.size = 15
        self.collected = False
        self.animation = 0
        
    def update(self):
        self.animation += 0.1
        
    def get_rect(self):
        return pygame.Rect(self.x - self.size, self.y - self.size, self.size * 2, self.size * 2)
        
    def draw(self, surface, camera_x):
        if not self.collected:
            screen_x = self.x - camera_x
            screen_y = self.y + math.sin(self.animation) * 5
            
            pygame.draw.circle(surface, COIN_COLOR, (int(screen_x), int(screen_y)), self.size)

# 玩家类
class Player:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.width = 30
        self.height = 50
        self.vx = 0
        self.vy = 0
        self.speed = 5
        self.jump_power = 12
        self.gravity = 0.5
        self.on_ground = False
        self.coins = 0
        self.health = 3
        self.invincible = 0
        
    def update(self, platforms, enemies, coins, camera_x):
        # 处理输入
        keys = pygame.key.get_pressed()
        
        # 水平移动
        if keys[pygame.K_LEFT] or keys[pygame.K_a]:
            self.vx = -self.speed
        elif keys[pygame.K_RIGHT] or keys[pygame.K_d]:
            self.vx = self.speed
        else:
            self.vx *= 0.8
            
        # 跳跃
        if (keys[pygame.K_SPACE] or keys[pygame.K_UP] or keys[pygame.K_w]) and self.on_ground:
            self.vy = -self.jump_power
            self.on_ground = False
            
        # 重力
        self.vy += self.gravity
        
        # 限制下落速度
        if self.vy > 15:
            self.vy = 15
            
        # 更新位置
        new_x = self.x + self.vx
        new_y = self.y + self.vy
        
        # 检查平台碰撞
        player_rect = pygame.Rect(new_x, new_y, self.width, self.height)
        self.on_ground = False
        
        for platform in platforms:
            platform_rect = platform.get_rect()
            
            if player_rect.colliderect(platform_rect):
                # 从上方落在平台上
                if self.vy > 0 and new_y + self.height - platform_rect.top < 10:
                    new_y = platform_rect.top - self.height
                    self.vy = 0
                    self.on_ground = True
                    
                    # 特殊平台效果
                    if platform.type == "spring":
                        self.vy = -self.jump_power * 1.5
                    elif platform.type == "jump_pad":
                        self.vy = -self.jump_power * 2
                    elif platform.type == "danger":
                        self.health -= 1
                        
                # 从侧面碰撞
                elif self.vx != 0:
                    if new_x < platform_rect.left and new_x + self.width > platform_rect.left:
                        new_x = platform_rect.left - self.width
                        self.vx = 0
                        
        # 检查敌人碰撞
        if self.invincible <= 0:
            player_rect = pygame.Rect(new_x, new_y, self.width, self.height)
            
            for enemy in enemies:
                enemy_rect = enemy.get_rect()
                
                if player_rect.colliderect(enemy_rect):
                    # 从上方踩到敌人
                    if self.vy > 0 and new_y + self.height - enemy_rect.top < 10:
                        new_y = enemy_rect.top - self.height
                        self.vy = -self.jump_power * 0.8
                        enemies.remove(enemy)
                    else:
                        self.health -= 1
                        self.invincible = 60
                        
        # 检查金币碰撞
        player_rect = pygame.Rect(new_x, new_y, self.width, self.height)
        
        for coin in coins[:]:
            if not coin.collected and player_rect.colliderect(coin.get_rect()):
                coin.collected = True
                self.coins += 1
        
        # 更新位置
        self.x = new_x
        self.y = new_y
        
        # 更新无敌时间
        if self.invincible > 0:
            self.invincible -= 1
            
        # 屏幕边界检测
        if self.x < 0:
            self.x = 0
        if self.x + self.width > 3000:
            self.x = 3000 - self.width
        if self.y > SCREEN_HEIGHT + 100:
            self.respawn(platforms)
            
    def respawn(self, platforms):
        self.x = 100
        self.y = 300
        self.vx = 0
        self.vy = 0
        self.health -= 1
        self.invincible = 60
        
        # 找到起始平台
        for platform in platforms:
            if platform.x < 200 and platform.x + platform.width > 100:
                self.y = platform.y - self.height
                break
                
    def draw(self, surface, camera_x):
        screen_x = self.x - camera_x
        screen_y = self.y
        
        # 无敌闪烁效果
        if self.invincible > 0 and self.invincible % 10 < 5:
            return
            
        pygame.draw.rect(surface, PLAYER_COLOR, (screen_x, screen_y, self.width, self.height))

# 游戏主类
class ParkourGame:
    def __init__(self):
        self.state = "menu"  # menu, playing, game_over, paused
        self.player = None
        self.platforms = []
        self.enemies = []
        self.coins = []
        self.camera_x = 0
        self.score = 0
        self.high_score = 0
        self.game_time = 0
        self.level = 1
        self.world_width = 3000
        self.generate_world()
        
    def generate_world(self):
        """生成游戏世界"""
        self.platforms = []
        self.enemies = []
        self.coins = []
        
        # 生成起始平台
        start_platform = Platform(50, 400, 200)
        self.platforms.append(start_platform)
        
        # 生成其他平台
        for i in range(20):
            x = 300 + i * 150
            y = 400 + random.randint(-50, 50)
            width = random.randint(80, 150)
            
            # 随机平台类型
            platform_type = "normal"
            if random.random() < 0.1:
                platform_type = "danger"
            elif random.random() < 0.1:
                platform_type = "spring"
            elif random.random() < 0.05:
                platform_type = "jump_pad"
                
            platform = Platform(x, y, width, platform_type)
            self.platforms.append(platform)
            
            # 在平台上生成敌人
            if random.random() < 0.3:
                enemy_x = x + width//2
                enemy_y = y - 40
                self.enemies.append(Enemy(enemy_x, enemy_y))
                
            # 在平台上生成金币
            if random.random() < 0.4:
                coin_x = x + random.randint(20, width - 20)
                coin_y = y - 30
                self.coins.append(Coin(coin_x, coin_y))
            
        # 创建玩家
        self.player = Player(100, 300)
        
    def update(self):
        """更新游戏状态"""
        if self.state == "playing":
            self.game_time += 1/60
            
            # 更新玩家
            self.player.update(self.platforms, self.enemies, self.coins, self.camera_x)
            
            # 更新敌人
            for enemy in self.enemies:
                enemy.update()
                
            # 更新金币
            for coin in self.coins:
                coin.update()
                
            # 更新相机
            target_x = self.player.x - SCREEN_WIDTH//3
            self.camera_x += (target_x - self.camera_x) * 0.1
            
            # 限制相机范围
            self.camera_x = max(0, min(self.camera_x, self.world_width - SCREEN_WIDTH))
            
            # 更新分数
            self.score = int(self.player.x // 10) + self.player.coins * 100
            
            # 检查游戏结束
            if self.player.health <= 0:
                self.state = "game_over"
                if self.score > self.high_score:
                    self.high_score = self.score
                    
    def draw_background(self, surface):
        """绘制背景 - 修复版"""
        # 天空渐变
        for y in range(SCREEN_HEIGHT):
            ratio = y / SCREEN_HEIGHT
            r = int(SKY_COLOR[0] * (1 - ratio) + 255 * ratio)
            g = int(SKY_COLOR[1] * (1 - ratio) + 255 * ratio)
            b = int(SKY_COLOR[2] * (1 - ratio) + 255 * ratio)
            pygame.draw.line(surface, (r, g, b), (0, y), (SCREEN_WIDTH, y))
            
        # 太阳
        sun_x = SCREEN_WIDTH - 100
        sun_y = 100
        pygame.draw.circle(surface, SUN_COLOR, (sun_x, sun_y), 40)
        
        # 修复：简化视差背景，避免颜色值越界
        for i in range(SCREEN_HEIGHT // 20):
            y = SCREEN_HEIGHT - i * 20
            
            # 使用安全的颜色值
            near_color = PARALLAX_NEAR
            mid_color = PARALLAX_MID
            far_color = PARALLAX_FAR
            
            for x in range(0, SCREEN_WIDTH, 40):
                parallax_x = (x + self.camera_x * 0.8) % 40
                pygame.draw.rect(surface, near_color, (parallax_x, y, 20, 5))
                
            for x in range(0, SCREEN_WIDTH, 60):
                parallax_x = (x + self.camera_x * 0.5) % 60
                pygame.draw.rect(surface, mid_color, (parallax_x, y, 30, 8))
                
            for x in range(0, SCREEN_WIDTH, 80):
                parallax_x = (x + self.camera_x * 0.3) % 80
                pygame.draw.rect(surface, far_color, (parallax_x, y, 40, 10))
                
    def draw_menu(self, surface):
        """绘制菜单"""
        self.draw_background(surface)
        
        # 标题
        title = font_huge.render("极限跑酷挑战", True, TEXT_COLOR)
        surface.blit(title, (SCREEN_WIDTH//2 - title.get_width()//2, 150))
        
        # 副标题
        subtitle = font_medium.render("按任意键开始游戏", True, TEXT_COLOR)
        surface.blit(subtitle, (SCREEN_WIDTH//2 - subtitle.get_width()//2, 230))
        
        # 控制说明
        controls = [
            "控制方式:",
            "← → 或 A D: 左右移动",
            "空格 或 W ↑: 跳跃",
            "ESC: 暂停/返回菜单",
            "",
            "游戏目标:",
            "1. 尽可能跑得更远",
            "2. 收集金币获取高分",
            "3. 避开危险平台和敌人"
        ]
        
        for i, control in enumerate(controls):
            control_text = font_small.render(control, True, TEXT_COLOR)
            surface.blit(control_text, (50, 300 + i * 25))
            
    def draw_game(self, surface):
        """绘制游戏"""
        # 绘制背景
        self.draw_background(surface)
        
        # 绘制平台
        for platform in self.platforms:
            if -100 < platform.x - self.camera_x < SCREEN_WIDTH + 100:
                platform.draw(surface, self.camera_x)
                
        # 绘制敌人
        for enemy in self.enemies:
            if -100 < enemy.x - self.camera_x < SCREEN_WIDTH + 100:
                enemy.draw(surface, self.camera_x)
                
        # 绘制金币
        for coin in self.coins:
            if -100 < coin.x - self.camera_x < SCREEN_WIDTH + 100:
                coin.draw(surface, self.camera_x)
                
        # 绘制玩家
        if -100 < self.player.x - self.camera_x < SCREEN_WIDTH + 100:
            self.player.draw(surface, self.camera_x)
            
        # 绘制UI
        self.draw_ui(surface)
        
    def draw_ui(self, surface):
        """绘制用户界面"""
        # 分数
        score_text = font_large.render(f"分数: {self.score}", True, TEXT_COLOR)
        surface.blit(score_text, (20, 20))
        
        # 金币
        coin_text = font_medium.render(f"金币: {self.player.coins}", True, COIN_COLOR)
        surface.blit(coin_text, (20, 70))
        
        # 生命值
        life_text = font_medium.render(f"生命: {self.player.health}", True, TEXT_COLOR)
        surface.blit(life_text, (SCREEN_WIDTH - 150, 20))
        
    def draw_game_over(self, surface):
        """绘制游戏结束界面"""
        # 绘制游戏
        self.draw_game(surface)
        
        # 半透明覆盖层
        overlay = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT))
        overlay.set_alpha(150)
        overlay.fill((0, 0, 0))
        surface.blit(overlay, (0, 0))
        
        # 游戏结束标题
        game_over = font_huge.render("游戏结束", True, TEXT_COLOR)
        surface.blit(game_over, (SCREEN_WIDTH//2 - game_over.get_width()//2, 150))
        
        # 显示分数
        score_text = font_large.render(f"分数: {self.score}", True, TEXT_COLOR)
        surface.blit(score_text, (SCREEN_WIDTH//2 - score_text.get_width()//2, 250))
        
        # 显示最高分
        high_score_text = font_medium.render(f"最高分: {self.high_score}", True, TEXT_COLOR)
        surface.blit(high_score_text, (SCREEN_WIDTH//2 - high_score_text.get_width()//2, 320))
        
        # 重新开始提示
        restart_text = font_medium.render("按 R 重新开始，ESC 返回菜单", True, TEXT_COLOR)
        surface.blit(restart_text, (SCREEN_WIDTH//2 - restart_text.get_width()//2, 450))
        
    def draw_paused(self, surface):
        """绘制暂停界面"""
        # 绘制游戏
        self.draw_game(surface)
        
        # 半透明覆盖层
        overlay = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT))
        overlay.set_alpha(150)
        overlay.fill((0, 0, 0))
        surface.blit(overlay, (0, 0))
        
        # 暂停标题
        paused = font_huge.render("游戏暂停", True, TEXT_COLOR)
        surface.blit(paused, (SCREEN_WIDTH//2 - paused.get_width()//2, 150))
        
        # 继续提示
        continue_text = font_medium.render("按 ESC 继续游戏", True, TEXT_COLOR)
        surface.blit(continue_text, (SCREEN_WIDTH//2 - continue_text.get_width()//2, 250))
        
    def handle_events(self):
        """处理事件"""
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
                
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    if self.state == "playing":
                        self.state = "paused"
                    elif self.state == "paused":
                        self.state = "playing"
                    elif self.state == "game_over":
                        self.state = "menu"
                    elif self.state == "menu":
                        self.state = "playing"
                        
                elif self.state == "menu":
                    # 按任意键开始游戏
                    self.state = "playing"
                    self.score = 0
                    self.level = 1
                    self.game_time = 0
                    self.generate_world()
                    
                elif self.state == "game_over" and event.key == pygame.K_r:
                    # 重新开始游戏
                    self.state = "playing"
                    self.score = 0
                    self.level = 1
                    self.game_time = 0
                    self.generate_world()
                    
    def draw(self, surface):
        """绘制整个游戏"""
        if self.state == "menu":
            self.draw_menu(surface)
        elif self.state == "playing":
            self.draw_game(surface)
        elif self.state == "game_over":
            self.draw_game_over(surface)
        elif self.state == "paused":
            self.draw_paused(surface)

def main():
    game = ParkourGame()
    
    while True:
        game.handle_events()
        game.update()
        game.draw(screen)
        pygame.display.flip()
        clock.tick(FPS)

if __name__ == "__main__":
    main()