import pygame
import random
import sys

# 初始化pygame
pygame.init()

# 游戏常量
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
FPS = 60

# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
BROWN = (139, 69, 19)
SKY_BLUE = (135, 206, 235)


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.on_ground = True
        self.jump_power = -15
        self.gravity = 0.8

    def jump(self):
        if self.on_ground:
            self.vel_y = self.jump_power
            self.jumping = True
            self.on_ground = False

    def update(self):
        # 应用重力
        self.vel_y += self.gravity
        self.y += self.vel_y

        # 地面碰撞检测
        ground_level = SCREEN_HEIGHT - 100
        if self.y + self.height >= ground_level:
            self.y = ground_level - self.height
            self.vel_y = 0
            self.on_ground = True
            self.jumping = False

    def draw(self, screen):
        # 绘制玩家角色（简单矩形）
        pygame.draw.rect(
            screen, BLUE, (self.x, self.y, self.width, self.height))
        # 绘制眼睛
        pygame.draw.circle(screen, WHITE, (self.x + 10, self.y + 15), 5)
        pygame.draw.circle(screen, WHITE, (self.x + 30, self.y + 15), 5)
        pygame.draw.circle(screen, BLACK, (self.x + 10, self.y + 15), 2)
        pygame.draw.circle(screen, BLACK, (self.x + 30, self.y + 15), 2)


class Obstacle:
    def __init__(self, x, y, width, height, obstacle_type="normal"):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.type = obstacle_type
        self.speed = 5
        self.passed = False

    def update(self):
        self.x -= self.speed

    def draw(self, screen):
        if self.type == "normal":
            color = RED
        elif self.type == "spike":
            color = (255, 100, 100)
        else:
            color = BROWN

        pygame.draw.rect(
            screen, color, (self.x, self.y, self.width, self.height))

        # 如果是尖刺障碍，绘制三角形
        if self.type == "spike":
            points = [(self.x, self.y + self.height),
                      (self.x + self.width, self.y + self.height),
                      (self.x + self.width // 2, self.y)]
            pygame.draw.polygon(screen, color, points)


class Game:
    def __init__(self):
        self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
        pygame.display.set_caption("跑酷游戏")
        self.clock = pygame.time.Clock()
        self.font = pygame.font.Font(None, 36)
        self.small_font = pygame.font.Font(None, 24)

        # 游戏状态
        self.running = True
        self.game_state = "menu"  # menu, playing, game_over
        self.score = 0
        self.high_score = 0

        # 游戏对象
        self.player = Player(100, SCREEN_HEIGHT - 160)
        self.obstacles = []
        self.obstacle_timer = 0
        self.obstacle_frequency = 60  # 每60帧生成一个障碍

        # 背景元素
        self.clouds = []
        for _ in range(5):
            x = random.randint(0, SCREEN_WIDTH)
            y = random.randint(50, 200)
            speed = random.uniform(0.5, 2)
            self.clouds.append([x, y, speed])

    def handle_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.running = False

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    if self.game_state == "playing":
                        self.player.jump()
                    elif self.game_state == "menu":
                        self.start_game()
                    elif self.game_state == "game_over":
                        self.start_game()

                if event.key == pygame.K_ESCAPE:
                    if self.game_state == "playing":
                        self.game_state = "menu"

    def start_game(self):
        self.game_state = "playing"
        self.score = 0
        self.player = Player(100, SCREEN_HEIGHT - 160)
        self.obstacles = []
        self.obstacle_timer = 0

    def update(self):
        if self.game_state != "playing":
            return

        # 更新玩家
        self.player.update()

        # 生成障碍物
        self.obstacle_timer += 1
        if self.obstacle_timer >= self.obstacle_frequency:
            self.obstacle_timer = 0
            # 随机选择障碍物类型
            obstacle_types = ["normal", "spike"]
            obstacle_type = random.choice(obstacle_types)

            if obstacle_type == "normal":
                width = random.randint(20, 40)
                height = random.randint(40, 80)
                y = SCREEN_HEIGHT - 100 - height
            else:  # spike
                width = 30
                height = 40
                y = SCREEN_HEIGHT - 100 - height

            self.obstacles.append(
                Obstacle(SCREEN_WIDTH, y, width, height, obstacle_type))

        # 更新障碍物
        for obstacle in self.obstacles[:]:
            obstacle.update()

            # 移除屏幕外的障碍物
            if obstacle.x + obstacle.width < 0:
                self.obstacles.remove(obstacle)
                self.score += 1
                if self.score > self.high_score:
                    self.high_score = self.score

            # 碰撞检测
            if (self.player.x < obstacle.x + obstacle.width and
                self.player.x + self.player.width > obstacle.x and
                self.player.y < obstacle.y + obstacle.height and
                    self.player.y + self.player.height > obstacle.y):
                self.game_state = "game_over"

    def draw_background(self):
        # 天空背景
        self.screen.fill(SKY_BLUE)

        # 绘制云朵
        for cloud in self.clouds:
            x, y, speed = cloud
            pygame.draw.ellipse(self.screen, WHITE, (x, y, 60, 30))
            pygame.draw.ellipse(self.screen, WHITE, (x + 20, y - 10, 50, 30))
            pygame.draw.ellipse(self.screen, WHITE, (x + 10, y + 10, 50, 30))

        # 地面
        pygame.draw.rect(self.screen, (34, 139, 34),
                         (0, SCREEN_HEIGHT - 100, SCREEN_WIDTH, 100))

        # 草地细节
        for i in range(0, SCREEN_WIDTH, 20):
            pygame.draw.line(self.screen, (0, 100, 0),
                             (i, SCREEN_HEIGHT - 100), (i, SCREEN_HEIGHT - 90), 2)

    def draw_menu(self):
        self.draw_background()

        # 标题
        title_text = self.font.render("跑酷游戏", True, BLACK)
        title_rect = title_text.get_rect(center=(SCREEN_WIDTH//2, 200))
        self.screen.blit(title_text, title_rect)

        # 操作说明
        instructions = [
            "按 SPACE 开始游戏",
            "按 SPACE 跳跃",
            "避开红色障碍物！",
            "ESC 返回菜单"
        ]

        for i, instruction in enumerate(instructions):
            text = self.small_font.render(instruction, True, BLACK)
            text_rect = text.get_rect(center=(SCREEN_WIDTH//2, 300 + i * 30))
            self.screen.blit(text, text_rect)

        # 显示最高分
        high_score_text = self.small_font.render(
            f"最高分: {self.high_score}", True, BLACK)
        high_score_rect = high_score_text.get_rect(
            center=(SCREEN_WIDTH//2, 450))
        self.screen.blit(high_score_text, high_score_rect)

    def draw_game(self):
        self.draw_background()

        # 绘制玩家
        self.player.draw(self.screen)

        # 绘制障碍物
        for obstacle in self.obstacles:
            obstacle.draw(self.screen)

        # 绘制分数
        score_text = self.font.render(f"分数: {self.score}", True, BLACK)
        self.screen.blit(score_text, (20, 20))

        high_score_text = self.small_font.render(
            f"最高分: {self.high_score}", True, BLACK)
        self.screen.blit(high_score_text, (20, 60))

    def draw_game_over(self):
        self.draw_game()

        # 半透明覆盖层
        overlay = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT))
        overlay.set_alpha(128)
        overlay.fill(BLACK)
        self.screen.blit(overlay, (0, 0))

        # 游戏结束文本
        game_over_text = self.font.render("游戏结束！", True, WHITE)
        game_over_rect = game_over_text.get_rect(center=(SCREEN_WIDTH//2, 250))
        self.screen.blit(game_over_text, game_over_rect)

        # 分数显示
        score_text = self.font.render(f"最终分数: {self.score}", True, WHITE)
        score_rect = score_text.get_rect(center=(SCREEN_WIDTH//2, 300))
        self.screen.blit(score_text, score_rect)

        # 重新开始提示
        restart_text = self.small_font.render("按 SPACE 重新开始", True, WHITE)
        restart_rect = restart_text.get_rect(center=(SCREEN_WIDTH//2, 350))
        self.screen.blit(restart_text, restart_rect)

    def draw(self):
        if self.game_state == "menu":
            self.draw_menu()
        elif self.game_state == "playing":
            self.draw_game()
        elif self.game_state == "game_over":
            self.draw_game_over()

        pygame.display.flip()

    def run(self):
        while self.running:
            self.handle_events()
            self.update()
            self.draw()
            self.clock.tick(FPS)

        pygame.quit()
        sys.exit()


if __name__ == "__main__":
    game = Game()
    game.run()
