import tkinter as tk
import random
import math

WIDTH, HEIGHT = 600, 300
GROUND_Y = 240
GRAVITY = 0.8
JUMP_POWER = -16
SCROLL_SPEED = 5

class Runner:
    def __init__(self, canvas):
        self.canvas = canvas
        self.x = 80
        self.y = GROUND_Y
        self.vy = 0
        self.on_ground = True
        self.double_jump = True

        self.id = canvas.create_rectangle(
            self.x - 15, self.y - 30,
            self.x + 15, self.y,
            fill="#4CAF50", outline="#2E7D32", width=2
        )

    def jump(self):
        if self.on_ground:
            self.vy = JUMP_POWER
            self.on_ground = False
            self.double_jump = True
        elif self.double_jump:
            self.vy = JUMP_POWER * 0.9
            self.double_jump = False

    def update(self):
        self.vy += GRAVITY
        self.y += self.vy

        if self.y >= GROUND_Y:
            self.y = GROUND_Y
            self.vy = 0
            self.on_ground = True

        self.canvas.coords(
            self.id,
            self.x - 15, self.y - 30,
            self.x + 15, self.y
        )

    def get_bounds(self):
        return self.canvas.coords(self.id)


class Obstacle:
    def __init__(self, canvas):
        self.canvas = canvas
        self.width = random.randint(20, 40)
        self.height = random.randint(30, 60)
        self.x = WIDTH + 50
        self.y = GROUND_Y

        self.id = canvas.create_rectangle(
            self.x - self.width // 2, self.y - self.height,
            self.x + self.width // 2, self.y,
            fill="#f44336", outline="#b71c1c", width=2
        )

    def update(self):
        self.x -= SCROLL_SPEED
        self.canvas.coords(
            self.id,
            self.x - self.width // 2, self.y - self.height,
            self.x + self.width // 2, self.y
        )

    def off_screen(self):
        return self.x + self.width // 2 < 0

    def get_bounds(self):
        return self.canvas.coords(self.id)

    def destroy(self):
        self.canvas.delete(self.id)


class ParkourGame:
    def __init__(self, root):
        self.root = root
        self.root.title("012. 跑酷游戏")
        self.root.resizable(False, False)

        self.canvas = tk.Canvas(
            root, width=WIDTH, height=HEIGHT, bg="#87CEEB"
        )
        self.canvas.pack()

        # 地面
        self.canvas.create_rectangle(
            0, GROUND_Y, WIDTH, HEIGHT,
            fill="#8BC34A", outline=""
        )

        # 云朵
        for _ in range(3):
            cx = random.randint(0, WIDTH)
            cy = random.randint(30, 100)
            self.canvas.create_oval(
                cx, cy, cx + 80, cy + 40,
                fill="white", outline=""
            )

        self.runner = Runner(self.canvas)
        self.obstacles = []
        self.score = 0
        self.game_over = False

        self.score_text = self.canvas.create_text(
            70, 30, text="得分: 0",
            font=("Arial", 16, "bold"), fill="white"
        )

        self.root.bind("<space>", lambda e: self.jump())
        self.spawn_obstacle()
        self.game_loop()

    def jump(self):
        if not self.game_over:
            self.runner.jump()

    def spawn_obstacle(self):
        if self.game_over:
            return
        self.obstacles.append(Obstacle(self.canvas))
        delay = random.randint(1200, 2200)
        self.root.after(delay, self.spawn_obstacle)

    def check_collision(self):
        runner_box = self.runner.get_bounds()
        for obs in self.obstacles:
            obs_box = obs.get_bounds()
            if (runner_box[2] > obs_box[0] and
                runner_box[0] < obs_box[2] and
                runner_box[3] > obs_box[1] and
                runner_box[1] < obs_box[3]):
                return True
        return False

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

        self.runner.update()

        for obs in self.obstacles[:]:
            obs.update()
            if obs.off_screen():
                obs.destroy()
                self.obstacles.remove(obs)
                self.score += 1
                self.canvas.itemconfig(
                    self.score_text, text=f"得分: {self.score}"
                )

        if self.check_collision():
            self.game_over = True
            self.canvas.create_text(
                WIDTH // 2, HEIGHT // 2,
                text="游戏结束！\n按空格键重新开始",
                font=("Arial", 24, "bold"),
                fill="yellow", justify=tk.CENTER
            )
            self.root.bind("<space>", lambda e: self.restart())
            return

        self.root.after(30, self.game_loop)

    def restart(self):
        self.canvas.delete("all")
        self.__init__(self.root)


if __name__ == "__main__":
    root = tk.Tk()
    ParkourGame(root)
    root.mainloop()