import pygame
import math
import random
import time

# === 初始化 ===
pygame.init()
pygame.mixer.init()

WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("🎮 趣味赛车小游戏")
clock = pygame.time.Clock()
FPS = 60

# === 颜色 ===
GRASS = (20, 150, 50)
ROAD = (60, 60, 60)
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (240, 50, 50)
BLUE = (50, 100, 240)
YELLOW = (255, 220, 0)
CYAN = (0, 220, 220)

# === 赛道边界 ===
ROAD_L = 150
ROAD_R = 650
ROAD_T = 100
ROAD_B = 500

# === AI 行驶路线 ===
track_points = [(200, 180), (600, 180), (600, 420), (200, 420), (200, 180)]

# === 生成赛车图片（不用外部图）===
def make_car(color):
    surf = pygame.Surface((32, 58), pygame.SRCALPHA)
    pygame.draw.rect(surf, color, (6, 0, 20, 58))
    pygame.draw.circle(surf, BLACK, (10, 10), 4)
    pygame.draw.circle(surf, BLACK, (22, 10), 4)
    pygame.draw.circle(surf, BLACK, (10, 48), 4)
    pygame.draw.circle(surf, BLACK, (22, 48), 4)
    return surf

# === 赛车基类 ===
class Car:
    def __init__(self, x, y, color):
        self.x = x
        self.y = y
        self.angle = 0
        self.speed = 0
        self.max_speed = 7
        self.acc = 0.25
        self.dec = 0.2
        self.turn_speed = 4.0
        self.drift = 0.6
        self.w, self.h = 32, 58
        self.img = make_car(color)
        self.out_road = False

    def check_bound(self):
        corners = [(-16, -29), (16, -29), (-16, 29), (16, 29)]
        rad = math.radians(self.angle)
        for dx, dy in corners:
            rx = dx * math.cos(rad) - dy * math.sin(rad)
            ry = dx * math.sin(rad) + dy * math.cos(rad)
            cx, cy = self.x + rx, self.y + ry
            if not (ROAD_L < cx < ROAD_R and ROAD_T < cy < ROAD_B):
                self.out_road = True
                return
        self.out_road = False

    def move(self):
        self.check_bound()
        if self.out_road:
            self.speed *= 0.85

        rad = math.radians(self.angle)
        self.x += math.sin(rad) * self.speed
        self.y -= math.cos(rad) * self.speed

    def draw(self):
        rotated = pygame.transform.rotate(self.img, self.angle)
        screen.blit(rotated, rotated.get_rect(center=(self.x, self.y)))

# === 玩家赛车 ===
class Player(Car):
    def __init__(self, x, y, color):
        super().__init__(x, y, color)
        self.nitro = 100
        self.lap = 0
        self.last_lap = 0
        self.best_lap = 999
        self.score = 0
        self.lap_st = time.time()
        self.cp = 0

    def control(self, keys):
        # 加速/减速
        if keys[pygame.K_UP]:
            self.speed += self.acc
        elif keys[pygame.K_DOWN]:
            self.speed -= self.acc * 1.8
        else:
            self.speed -= self.dec if self.speed > 0 else -self.dec

        # 氮气
        if keys[pygame.K_SPACE] and self.nitro > 5:
            self.speed += 0.5
            self.nitro -= 1.2
        else:
            self.nitro = min(100, self.nitro + 0.3)

        # 限速
        limit = self.max_speed * 1.8 if keys[pygame.K_SPACE] else self.max_speed
        self.speed = max(-3, min(limit, self.speed))

        # 漂移转向
        if abs(self.speed) > 0.4:
            mul = self.drift if keys[pygame.K_LSHIFT] else 1
            rate = self.speed / self.max_speed
            if keys[pygame.K_LEFT]:
                self.angle -= self.turn_speed * rate * mul
            if keys[pygame.K_RIGHT]:
                self.angle += self.turn_speed * rate * mul

        # 圈数计算
        if 190 < self.x < 210 and ROAD_T - 10 < self.y < ROAD_T + 10:
            if self.cp == 0:
                t = round(time.time() - self.lap_st, 2)
                if t > 1.5:
                    self.lap += 1
                    self.last_lap = t
                    if t < self.best_lap:
                        self.best_lap = t
                self.lap_st = time.time()
                self.cp = 1
        elif 190 < self.x < 210:
            self.cp = 0

# === AI 赛车 ===
class AI(Car):
    def __init__(self, x, y, color):
        super().__init__(x, y, color)
        self.tg = 0
        self.spd = random.uniform(4.2, 4.8)

    def ai_run(self):
        tx, ty = track_points[self.tg]
        dx, dy = tx - self.x, ty - self.y
        target_angle = math.degrees(math.atan2(dx, -dy))
        diff = (target_angle - self.angle + 180) % 360 - 180
        self.angle += diff * 0.05

        self.speed = self.spd if not self.out_road else self.spd * 0.7
        if math.hypot(dx, dy) < 50:
            self.tg = (self.tg + 1) % 5

# === 道具系统 ===
class Item:
    def __init__(self):
        self.reset()

    def reset(self):
        self.x = random.randint(ROAD_L + 50, ROAD_R - 50)
        self.y = random.randint(ROAD_T + 50, ROAD_B - 50)
        self.kind = random.choice(["nitro", "score", "shield"])

    def draw(self):
        c = YELLOW if self.kind == "nitro" else (CYAN if self.kind == "shield" else WHITE)
        pygame.draw.circle(screen, c, (int(self.x), int(self.y)), 10)

# === 游戏初始化 ===
player = Player(250, 300, RED)
ai1 = AI(320, 300, BLUE)
item = Item()
font = pygame.font.SysFont("simhei", 24)

# === 主游戏循环 ===
running = True
while running:
    screen.fill(GRASS)
    clock.tick(FPS)

    # 画赛道
    pygame.draw.rect(screen, ROAD, (ROAD_L, ROAD_T, ROAD_R - ROAD_L, ROAD_B - ROAD_T), border_radius=20)
    pygame.draw.rect(screen, WHITE, (195, ROAD_T - 8, 10, 16))

    # 道具
    item.draw()
    if math.hypot(player.x - item.x, player.y - item.y) < 22:
        if item.kind == "nitro":
            player.nitro = 100
        elif item.kind == "score":
            player.score += 30
        item.reset()

    # 事件
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    # 玩家
    player.control(pygame.key.get_pressed())
    player.move()
    player.draw()

    # AI
    ai1.ai_run()
    ai1.move()
    ai1.draw()

    # UI 显示
    ui_text = [
        f"🏁 圈数：{player.lap}",
        f"⏱ 单圈：{player.last_lap}s",
        f"🏆 最佳：{player.best_lap}s",
        f"⚡ 氮气：{int(player.nitro)}%",
        f"⭐ 得分：{player.score}"
    ]
    for i, t in enumerate(ui_text):
        surf = font.render(t, True, WHITE, BLACK)
        screen.blit(surf, (20, 30 + i * 35))

    pygame.display.flip()

pygame.quit()