import pygame
import sys
import random
from pygame.locals import *

# 初始化 Pygame
pygame.init()

# 游戏窗口设置
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("跑酷小游戏 - 跳跃冒险")

# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 50, 50)
GREEN = (50, 255, 50)
BLUE = (50, 100, 255)
YELLOW = (255, 255, 50)
ORANGE = (255, 165, 0)
PURPLE = (180, 50, 230)
CYAN = (0, 255, 255)
GRAY = (100, 100, 100)
LIGHT_GRAY = (200, 200, 200)
SKY_BLUE = (135, 206, 235)
GRASS_GREEN = (60, 180, 75)
GROUND_COLOR = (139, 115, 85)

# 加载字体
try:
    font_large = pygame.font.Font(None, 48)
    font_medium = pygame.font.Font(None, 36)
    font_small = pygame.font.Font(None, 24)
    font_tiny = pygame.font.Font(None, 20)
except:
    font_large = pygame.font.SysFont(None, 48)
    font_medium = pygame.font.SysFont(None, 36)
    font_small = pygame.font.SysFont(None, 24)
    font_tiny = pygame.font.SysFont(None, 20)

# 游戏参数
FPS = 60
GRAVITY = 0.8
JUMP_STRENGTH = 15
GAME_SPEED = 5
GROUND_HEIGHT = 50
PLAYER_WIDTH = 40
PLAYER_HEIGHT = 60
OBSTACLE_WIDTH = 40
OBSTACLE_HEIGHT = 60
COIN_SIZE = 20

class Player:
    """玩家类"""
    def __init__(self):
        self.x = 150
        self.y = HEIGHT - GROUND_HEIGHT - PLAYER_HEIGHT
        self.width = PLAYER_WIDTH
        self.height = PLAYER_HEIGHT
        self.y_velocity = 0
        self.is_jumping = False
        self.color = BLUE
        self.score = 0
        self.coins = 0
        self.jump_count = 0
        self.animation_frame = 0
        self.visible = True
        self.blink_timer = 0
        
    def update(self, keys):
        """更新玩家状态"""
        self.animation_frame += 1
        
        # 处理跳跃
        if (keys[K_SPACE] or keys[K_UP] or keys[K_w]) and not self.is_jumping:
            self.jump()
        
        # 应用重力
        if self.is_jumping:
            self.y += self.y_velocity
            self.y_velocity += GRAVITY
            
            # 检查是否落地
            if self.y >= HEIGHT - GROUND_HEIGHT - self.height:
                self.y = HEIGHT - GROUND_HEIGHT - self.height
                self.is_jumping = False
                self.y_velocity = 0
                self.jump_count = 0
        
        # 更新闪烁效果
        if self.blink_timer > 0:
            self.blink_timer -= 1
            self.visible = (self.blink_timer // 5) % 2 == 0
        else:
            self.visible = True
    
    def jump(self):
        """跳跃"""
        self.is_jumping = True
        self.y_velocity = -JUMP_STRENGTH
        self.jump_count += 1
        self.color = CYAN if self.jump_count > 1 else BLUE
    
    def take_damage(self):
        """受到伤害"""
        if self.blink_timer == 0:
            self.blink_timer = 60
            return True
        return False
    
    def collect_coin(self, value):
        """收集金币"""
        self.coins += 1
        self.score += value
        self.color = YELLOW
    
    def draw(self, screen):
        """绘制玩家"""
        if not self.visible:
            return
            
        x, y = int(self.x), int(self.y)
        
        # 绘制身体
        pygame.draw.rect(screen, self.color, (x, y, self.width, self.height))
        
        # 绘制头部
        head_radius = self.width // 3
        head_x = x + self.width // 2
        head_y = y - head_radius // 2
        pygame.draw.circle(screen, LIGHT_GRAY, (head_x, head_y), head_radius)
        
        # 绘制眼睛
        eye_radius = 3
        pygame.draw.circle(screen, BLACK, (head_x - 8, head_y - 3), eye_radius)
        pygame.draw.circle(screen, BLACK, (head_x + 8, head_y - 3), eye_radius)
        
        # 绘制嘴巴
        if self.is_jumping:
            pygame.draw.circle(screen, RED, (head_x, head_y + 5), 4)
        else:
            pygame.draw.arc(screen, RED, (head_x - 10, head_y, 20, 10), 0, 3.14, 2)
        
        # 绘制手臂摆动
        arm_swing = 0
        if not self.is_jumping:
            # 简单摆动效果
            if (self.animation_frame // 10) % 2 == 0:
                arm_swing = 10
            else:
                arm_swing = -10
        
        # 绘制手臂
        pygame.draw.line(screen, self.color, (x, y + 20), 
                        (x - 20, y + 20 + arm_swing), 8)
        pygame.draw.line(screen, self.color, (x + self.width, y + 20), 
                        (x + self.width + 20, y + 20 - arm_swing), 8)
        
        # 绘制腿部
        if self.is_jumping:
            pygame.draw.line(screen, self.color, (x + 10, y + self.height), 
                           (x, y + self.height + 30), 8)
            pygame.draw.line(screen, self.color, (x + self.width - 10, y + self.height), 
                           (x + self.width, y + self.height + 30), 8)
        else:
            leg_swing = 0
            if (self.animation_frame // 10) % 2 == 0:
                leg_swing = 10
            else:
                leg_swing = -10
            
            pygame.draw.line(screen, self.color, (x + 10, y + self.height), 
                           (x, y + self.height + 30 + leg_swing), 8)
            pygame.draw.line(screen, self.color, (x + self.width - 10, y + self.height), 
                           (x + self.width, y + self.height + 30 - leg_swing), 8)
    
    def get_rect(self):
        """获取碰撞矩形"""
        return pygame.Rect(self.x, self.y, self.width, self.height)

class Obstacle:
    """障碍物类"""
    def __init__(self, obstacle_type=1):
        self.x = WIDTH
        self.y = HEIGHT - GROUND_HEIGHT
        self.type = obstacle_type
        
        if obstacle_type == 1:  # 高障碍物
            self.width = OBSTACLE_WIDTH
            self.height = OBSTACLE_HEIGHT
            self.y -= self.height
            self.color = RED
        else:  # 宽障碍物
            self.width = 80
            self.height = 40
            self.y -= self.height
            self.color = ORANGE
        
    def update(self):
        """更新障碍物位置"""
        self.x -= GAME_SPEED
    
    def draw(self, screen):
        """绘制障碍物"""
        pygame.draw.rect(screen, self.color, (self.x, self.y, self.width, self.height))
        
        # 绘制障碍物图案
        if self.type == 1:
            pygame.draw.rect(screen, BLACK, (self.x + 10, self.y + 10, 20, 20))
        else:
            pygame.draw.rect(screen, BLACK, (self.x + 20, self.y + 10, 40, 20))
    
    def is_off_screen(self):
        """检查是否离开屏幕"""
        return self.x < -self.width
    
    def get_rect(self):
        """获取碰撞矩形"""
        return pygame.Rect(self.x, self.y, self.width, self.height)

class Coin:
    """金币类"""
    def __init__(self):
        self.x = WIDTH
        self.y = random.randint(HEIGHT - GROUND_HEIGHT - 150, HEIGHT - GROUND_HEIGHT - 50)
        self.size = COIN_SIZE
        self.value = 10
        self.collected = False
        self.rotation = 0
        
    def update(self):
        """更新金币位置"""
        self.x -= GAME_SPEED
        self.rotation = (self.rotation + 5) % 360
    
    def draw(self, screen):
        """绘制金币"""
        if self.collected:
            return
            
        x, y = int(self.x), int(self.y)
        
        # 绘制金币
        pygame.draw.circle(screen, YELLOW, (x, y), self.size)
        pygame.draw.circle(screen, (200, 180, 0), (x, y), self.size, 3)
        
        # 绘制金币符号
        coin_text = font_small.render("$", True, BLACK)
        text_rect = coin_text.get_rect(center=(x, y))
        screen.blit(coin_text, text_rect)
    
    def is_off_screen(self):
        """检查是否离开屏幕"""
        return self.x < -self.size
    
    def get_rect(self):
        """获取碰撞矩形"""
        return pygame.Rect(self.x - self.size, self.y - self.size, 
                          self.size * 2, self.size * 2)

class Game:
    """游戏主类"""
    def __init__(self):
        self.player = None
        self.obstacles = []
        self.coins = []
        self.score = 0
        self.high_score = 0
        self.game_state = "start"  # start, playing, game_over
        self.obstacle_timer = 0
        self.coin_timer = 0
        self.game_time = 0
        
        self.init_game()
    
    def init_game(self):
        """初始化游戏"""
        self.player = Player()
        self.obstacles = []
        self.coins = []
        self.obstacle_timer = 0
        self.coin_timer = 0
        self.game_time = 0
        self.score = 0
    
    def update(self):
        """更新游戏状态"""
        if self.game_state != "playing":
            return
        
        self.game_time += 1
        
        # 生成障碍物
        self.obstacle_timer += 1
        if self.obstacle_timer >= 60:  # 每秒生成一个障碍物
            self.obstacle_timer = 0
            obstacle_type = random.choice([1, 2])
            self.obstacles.append(Obstacle(obstacle_type))
        
        # 生成金币
        self.coin_timer += 1
        if self.coin_timer >= 30:  # 每0.5秒可能生成一个金币
            self.coin_timer = 0
            if random.random() < 0.3:  # 30%的几率生成金币
                self.coins.append(Coin())
        
        # 更新障碍物
        for obstacle in self.obstacles[:]:
            obstacle.update()
            
            # 检查碰撞
            if self.player.get_rect().colliderect(obstacle.get_rect()):
                if self.player.take_damage():
                    self.game_state = "game_over"
                    if self.score > self.high_score:
                        self.high_score = self.score
            
            if obstacle.is_off_screen():
                self.obstacles.remove(obstacle)
        
        # 更新金币
        for coin in self.coins[:]:
            coin.update()
            
            # 检查收集
            if self.player.get_rect().colliderect(coin.get_rect()):
                self.player.collect_coin(coin.value)
                self.score += coin.value
                coin.collected = True
            
            if coin.is_off_screen() or coin.collected:
                if coin in self.coins:
                    self.coins.remove(coin)
    
    def draw(self, screen):
        """绘制游戏"""
        # 绘制天空
        screen.fill(SKY_BLUE)
        
        # 绘制地面
        pygame.draw.rect(screen, GROUND_COLOR, (0, HEIGHT - GROUND_HEIGHT, WIDTH, GROUND_HEIGHT))
        
        # 绘制地面纹理
        for i in range(0, WIDTH, 50):
            pygame.draw.line(screen, (100, 80, 60), 
                           (i, HEIGHT - GROUND_HEIGHT), 
                           (i, HEIGHT - GROUND_HEIGHT + 10), 2)
        
        # 绘制云朵
        for i in range(3):
            cloud_x = (self.game_time + i * 200) % (WIDTH + 300) - 100
            cloud_y = 100 + i * 30
            cloud_size = 20 + i * 5
            
            pygame.draw.circle(screen, WHITE, (int(cloud_x), cloud_y), cloud_size)
            pygame.draw.circle(screen, WHITE, (int(cloud_x) - cloud_size//2, cloud_y), cloud_size//2)
            pygame.draw.circle(screen, WHITE, (int(cloud_x) + cloud_size//2, cloud_y), cloud_size//2)
        
        # 绘制金币
        for coin in self.coins:
            coin.draw(screen)
        
        # 绘制障碍物
        for obstacle in self.obstacles:
            obstacle.draw(screen)
        
        # 绘制玩家
        self.player.draw(screen)
        
        # 绘制HUD
        self.draw_hud(screen)
        
        # 绘制游戏状态界面
        if self.game_state == "start":
            self.draw_start_screen(screen)
        elif self.game_state == "game_over":
            self.draw_game_over_screen(screen)
    
    def draw_hud(self, screen):
        """绘制游戏信息界面"""
        # 绘制分数
        score_text = font_medium.render(f"分数: {self.score}", True, BLACK)
        screen.blit(score_text, (20, 20))
        
        # 绘制金币
        coins_text = font_medium.render(f"金币: {self.player.coins}", True, YELLOW)
        screen.blit(coins_text, (20, 60))
        
        # 绘制时间
        time_text = font_medium.render(f"时间: {self.game_time//60}秒", True, BLACK)
        screen.blit(time_text, (WIDTH - 150, 20))
        
        # 绘制最高分
        high_score_text = font_small.render(f"最高分: {self.high_score}", True, BLACK)
        screen.blit(high_score_text, (WIDTH - 150, 60))
    
    def draw_start_screen(self, screen):
        """绘制开始画面"""
        overlay = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)
        overlay.fill((0, 0, 0, 150))
        screen.blit(overlay, (0, 0))
        
        # 标题
        title_text = font_large.render("跑酷小游戏", True, BLUE)
        screen.blit(title_text, (WIDTH//2 - 100, HEIGHT//2 - 100))
        
        # 游戏说明
        instructions = [
            "游戏目标: 尽可能跑得远，避开障碍物，收集金币",
            "",
            "控制说明:",
            "空格键/↑/W: 跳跃",
            "",
            "游戏元素:",
            "蓝色小人: 玩家角色",
            "红色障碍: 高障碍物 - 需要跳跃",
            "橙色障碍: 宽障碍物 - 可以跳过或躲避",
            "金币 $: 收集获得10分",
            "",
            "提示: 掌握跳跃时机是关键!"
        ]
        
        for i, instruction in enumerate(instructions):
            color = YELLOW if i == 0 else WHITE
            instruction_text = font_small.render(instruction, True, color)
            screen.blit(instruction_text, (WIDTH//2 - 200, HEIGHT//2 - 30 + i * 25))
        
        # 开始游戏提示
        start_text = font_medium.render("按空格键开始游戏", True, GREEN)
        screen.blit(start_text, (WIDTH//2 - 120, HEIGHT - 100))
    
    def draw_game_over_screen(self, screen):
        """绘制游戏结束画面"""
        overlay = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)
        overlay.fill((0, 0, 0, 150))
        screen.blit(overlay, (0, 0))
        
        # 游戏结束文字
        game_over_text = font_large.render("游戏结束!", True, RED)
        screen.blit(game_over_text, (WIDTH//2 - 100, HEIGHT//2 - 100))
        
        # 统计信息
        stats = [
            f"最终分数: {self.score}",
            f"收集金币: {self.player.coins}枚",
            f"坚持时间: {self.game_time//60}秒",
            f"最高分数: {self.high_score}"
        ]
        
        for i, stat in enumerate(stats):
            stat_text = font_medium.render(stat, True, WHITE)
            screen.blit(stat_text, (WIDTH//2 - 100, HEIGHT//2 - 50 + i * 40))
        
        # 重新开始提示
        restart_text = font_medium.render("按R键重新开始", True, GREEN)
        screen.blit(restart_text, (WIDTH//2 - 80, HEIGHT//2 + 120))
        
        menu_text = font_medium.render("按ESC键返回菜单", True, YELLOW)
        screen.blit(menu_text, (WIDTH//2 - 100, HEIGHT//2 + 170))
    
    def restart_game(self):
        """重新开始游戏"""
        self.init_game()
        self.game_state = "playing"

def main():
    """主游戏函数"""
    clock = pygame.time.Clock()
    game = Game()
    
    # 主游戏循环
    running = True
    while running:
        clock.tick(FPS)
        
        # 获取按键状态
        keys = pygame.key.get_pressed()
        
        # 处理事件
        for event in pygame.event.get():
            if event.type == QUIT:
                running = False
            elif event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    if game.game_state in ["playing", "game_over"]:
                        game.game_state = "start"
                    else:
                        running = False
                elif event.key == K_SPACE:
                    if game.game_state == "start":
                        game.game_state = "playing"
                elif event.key == K_r:
                    if game.game_state == "game_over":
                        game.restart_game()
        
        # 更新玩家
        if game.game_state == "playing":
            game.player.update(keys)
            
        # 更新游戏状态
        game.update()
        
        # 绘制游戏
        game.draw(screen)
        
        pygame.display.flip()
    
    pygame.quit()
    sys.exit()

if __name__ == "__main__":
    main()