import pygame
import random
import math
import sys
import time

# 初始化pygame
pygame.init()

# 屏幕设置
SCREEN_WIDTH = 1200
SCREEN_HEIGHT = 800
FPS = 60

# 颜色定义
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 50, 50)
GREEN = (50, 255, 50)
BLUE = (0, 100, 255)
YELLOW = (255, 255, 0)
PURPLE = (180, 0, 180)
ORANGE = (255, 150, 0)
CYAN = (0, 200, 255)
PINK = (255, 100, 180)
GRAY = (100, 100, 100)
DARK_GRAY = (50, 50, 50)
LIGHT_GRAY = (200, 200, 200)
DARK_GREEN = (0, 100, 0)
ROAD_COLOR = (40, 40, 40)
LANE_COLOR = (200, 200, 0)
GRASS_COLOR = (0, 150, 0)
SKY_COLOR = (135, 206, 235)
CLOUD_COLOR = (240, 240, 240)
WALL_COLOR = (60, 60, 80)
GRID_COLOR = (80, 80, 100)
GRASS_DARK = (0, 120, 0)
GRASS_LIGHT = (0, 180, 0)
CROWD_COLOR = (30, 30, 30)
GRANDSTAND_COLOR = (80, 40, 20)
FLAG_COLOR = (255, 0, 0)

# 游戏参数
TRACK_WIDTH = 800
TRACK_CURVE = 0.1
CAR_WIDTH = 40
CAR_HEIGHT = 80
CAR_SPEED = 5
AI_CAR_WIDTH = 40
AI_CAR_HEIGHT = 80
AI_CAR_SPEED = 4
CHECKPOINT_SIZE = 20
ITEM_SIZE = 20
EXPLOSION_SIZE = 50
SMOKE_SIZE = 30
NITRO_SIZE = 30
SHIELD_SIZE = 30
TURBO_SIZE = 30
OIL_SIZE = 25
SPIKE_SIZE = 20
GRID_SIZE = 50
GRASS_PATTERN = 20
CROWD_SIZE = 20
GRANDSTAND_WIDTH = 200
GRANDSTAND_HEIGHT = 300
FLAG_WIDTH = 10
FLAG_HEIGHT = 60
LAP_DISTANCE = 5000
TRACK_SEGMENTS = 100
MIN_RADIUS = 200
MAX_RADIUS = 500

# 字体


def get_font(size, bold=False):
    try:
        if bold:
            return pygame.font.SysFont("arial", size, bold=True)
        return pygame.font.SysFont("arial", size)
    except:
        return pygame.font.Font(None, size)


font_small = get_font(20)
font_medium = get_font(30)
font_large = get_font(50, bold=True)
font_title = get_font(60, bold=True)


class Particle:
    def __init__(self, x, y, color, velocity, lifetime=30, size=3):
        self.x = x
        self.y = y
        self.color = color
        self.vx, self.vy = velocity
        self.lifetime = lifetime
        self.max_lifetime = lifetime
        self.size = size
        self.gravity = random.uniform(0.05, 0.2)

    def update(self):
        self.x += self.vx
        self.y += self.vy
        self.vy += self.gravity
        self.vx *= 0.95
        self.vy *= 0.95
        self.lifetime -= 1
        self.size = max(1, self.size * 0.9)
        return self.lifetime > 0

    def draw(self, screen):
        if self.lifetime > 0:
            alpha = int(255 * (self.lifetime / self.max_lifetime))
            temp_surface = pygame.Surface(
                (self.size*2, self.size*2), pygame.SRCALPHA)
            if len(self.color) == 4:
                r, g, b, a = self.color
                pygame.draw.circle(temp_surface, (r, g, b, min(alpha, a)),
                                   (self.size, self.size), self.size)
            else:
                pygame.draw.circle(temp_surface, (*self.color, alpha),
                                   (self.size, self.size), self.size)
            screen.blit(temp_surface, (int(self.x) -
                        self.size, int(self.y)-self.size))


class Car:
    def __init__(self, x, y, color, is_player=False, car_type="sports"):
        self.x = x
        self.y = y
        self.width = CAR_WIDTH
        self.height = CAR_HEIGHT
        self.color = color
        self.is_player = is_player
        self.car_type = car_type

        # 物理属性
        self.speed = 0
        self.max_speed = 8 if car_type == "sports" else 6
        self.acceleration = 0.2
        self.braking = 0.3
        self.turn_speed = 4
        self.drift_factor = 0.1
        self.traction = 0.9
        self.health = 100
        self.fuel = 100
        self.nitro = 0
        self.shield = 0

        # 状态
        self.direction = 0
        self.velocity_x = 0
        self.velocity_y = 0
        self.drift_angle = 0
        self.on_oil = False
        self.on_spike = False
        self.nitro_active = False
        self.shield_active = False
        self.turbo_active = False
        self.invincible = False
        self.invincible_time = 0

        # 视觉效果
        self.skid_marks = []
        self.particles = []
        self.trail = []
        self.smoke_timer = 0
        self.explosion_timer = 0

        # 比赛状态
        self.lap = 0
        self.checkpoint = 0
        self.position = 0
        self.race_time = 0
        self.best_lap = 999999
        self.last_lap_time = 0

        # AI属性
        if not is_player:
            self.aggression = random.uniform(0.3, 0.9)
            self.skill = random.uniform(0.5, 1.0)
            self.patience = random.uniform(0.2, 0.8)
            self.ai_timer = 0
            self.ai_target_x = x
            self.ai_target_y = y
            self.ai_avoidance = 0

    def update(self, keys, track_points, cars, items, dt):
        if self.is_player:
            self._player_control(keys, dt)
        else:
            self._ai_control(track_points, cars, items, dt)

        # 应用物理
        self._apply_physics(dt)

        # 更新特效
        self._update_effects()

        # 更新比赛时间
        if self.speed > 0:
            self.race_time += dt

        return True

    def _player_control(self, keys, dt):
        # 加速/刹车
        if keys[pygame.K_w] or keys[pygame.K_UP]:
            self.speed = min(self.speed + self.acceleration, self.max_speed)
        elif keys[pygame.K_s] or keys[pygame.K_DOWN]:
            self.speed = max(self.speed - self.braking, -self.max_speed * 0.5)
        else:
            # 自然减速
            self.speed *= 0.98

        # 转向
        turning = 0
        if keys[pygame.K_a] or keys[pygame.K_LEFT]:
            turning = -1
        if keys[pygame.K_d] or keys[pygame.K_RIGHT]:
            turning = 1

        # 应用转向
        if abs(self.speed) > 0.1:
            turn_multiplier = 1.0
            if self.on_oil:
                turn_multiplier = 2.0
            self.direction += turning * self.turn_speed * \
                (self.speed / self.max_speed) * turn_multiplier
            self.direction %= 360

        # 氮气加速
        if keys[pygame.K_SPACE] and self.nitro > 0 and not self.nitro_active:
            self.nitro_active = True
            self.max_speed = 12

        # 漂移效果
        if abs(turning) > 0.5 and self.speed > 3 and random.random() < 0.3:
            self._create_skid_mark()

        # 生成烟雾
        if self.speed > 5 and random.random() < 0.1:
            self._create_smoke()

    def _ai_control(self, track_points, cars, items, dt):
        self.ai_timer += dt

        # 每0.5秒重新计算AI行为
        if self.ai_timer > 0.5:
            self.ai_timer = 0

            # 找到最近的赛道点
            nearest_idx = 0
            min_dist = float('inf')
            for i, (tx, ty) in enumerate(track_points):
                dist = math.sqrt((self.x - tx)**2 + (self.y - ty)**2)
                if dist < min_dist:
                    min_dist = dist
                    nearest_idx = i

            # 目标点是前方一定距离的赛道点
            target_idx = (nearest_idx + 5) % len(track_points)
            self.ai_target_x, self.ai_target_y = track_points[target_idx]

            # 避让其他车辆
            avoidance = 0
            for car in cars:
                if car != self:
                    dist = math.sqrt((self.x - car.x)**2 + (self.y - car.y)**2)
                    if dist < 100:
                        dx = car.x - self.x
                        avoidance = -dx / dist * 50
                        break
            self.ai_avoidance = avoidance

        # 转向目标点
        dx = self.ai_target_x - self.x + self.ai_avoidance
        dy = self.ai_target_y - self.y
        target_angle = math.degrees(math.atan2(dy, dx))

        # 平滑转向
        angle_diff = (target_angle - self.direction) % 360
        if angle_diff > 180:
            angle_diff -= 360

        turn_strength = min(abs(angle_diff) / 180, 1.0) * self.skill
        if angle_diff > 0:
            self.direction += self.turn_speed * turn_strength
        else:
            self.direction -= self.turn_speed * turn_strength

        # AI加速逻辑
        if self.speed < self.max_speed * self.skill:
            self.speed = min(self.speed + self.acceleration *
                             0.5, self.max_speed * self.skill)

        # AI偶尔使用氮气
        if self.nitro > 50 and random.random() < 0.01 and not self.nitro_active:
            self.nitro_active = True
            self.max_speed = 10

        # AI漂移
        if abs(angle_diff) > 30 and self.speed > 4 and random.random() < 0.1:
            self._create_skid_mark()

    def _apply_physics(self, dt):
        # 计算移动
        rad = math.radians(self.direction)
        self.velocity_x = math.cos(rad) * self.speed
        self.velocity_y = math.sin(rad) * self.speed

        # 应用移动
        self.x += self.velocity_x
        self.y += self.velocity_y

        # 摩擦力和漂移
        if not self.on_oil:
            self.velocity_x *= self.traction
            self.velocity_y *= self.traction

        # 氮气效果
        if self.nitro_active:
            self.nitro -= 0.5
            if self.nitro <= 0:
                self.nitro_active = False
                self.max_speed = 8
            # 氮气粒子
            if random.random() < 0.3:
                self._create_nitro_particle()

        # 护盾效果
        if self.shield_active:
            self.shield -= 1
            if self.shield <= 0:
                self.shield_active = False

        # 涡轮效果
        if self.turbo_active:
            self.turbo_active = False

        # 无敌时间
        if self.invincible:
            self.invincible_time -= 1
            if self.invincible_time <= 0:
                self.invincible = False

        # 燃料消耗
        if self.speed > 0:
            self.fuel -= 0.01 * (self.speed / self.max_speed)
            self.fuel = max(0, self.fuel)

        # 更新轨迹
        self.trail.append((self.x, self.y))
        if len(self.trail) > 10:
            self.trail.pop(0)

    def _update_effects(self):
        # 更新轮胎痕迹
        for skid in self.skid_marks[:]:
            skid['lifetime'] -= 1
            if skid['lifetime'] <= 0:
                self.skid_marks.remove(skid)

        # 更新粒子
        for particle in self.particles[:]:
            if not particle.update():
                self.particles.remove(particle)

    def _create_skid_mark(self):
        angle = math.radians(self.direction + 90)
        offset_x = math.cos(angle) * 20
        offset_y = math.sin(angle) * 20
        self.skid_marks.append({
            'x': self.x + offset_x,
            'y': self.y + offset_y,
            'lifetime': 100
        })

    def _create_smoke(self):
        angle = math.radians(self.direction + 180)
        self.particles.append(Particle(
            self.x + math.cos(angle) * 20,
            self.y + math.sin(angle) * 20,
            (100, 100, 100),
            (-self.velocity_x * 0.5, -self.velocity_y * 0.5),
            30, 5
        ))

    def _create_nitro_particle(self):
        angle = math.radians(self.direction + 180)
        self.particles.append(Particle(
            self.x + math.cos(angle) * 20,
            self.y + math.sin(angle) * 20,
            CYAN,
            (-math.cos(angle) * 3, -math.sin(angle) * 3),
            20, 4
        ))

    def draw(self, screen, camera_x, camera_y):
        # 绘制轨迹
        for i, (tx, ty) in enumerate(self.trail):
            alpha = int(255 * (i / len(self.trail)))
            pygame.draw.circle(screen, (*self.color[:3], alpha//3),
                               (int(tx - camera_x), int(ty - camera_y)), 3)

        # 绘制轮胎痕迹
        for skid in self.skid_marks:
            alpha = int(255 * (skid['lifetime'] / 100))
            pygame.draw.circle(screen, (100, 100, 100, alpha),
                               (int(skid['x'] - camera_x), int(skid['y'] - camera_y)), 8)

        # 绘制粒子
        for particle in self.particles:
            particle.draw(screen)

        # 计算旋转角度
        angle = self.direction
        rad = math.radians(angle)
        cos_a = math.cos(rad)
        sin_a = math.sin(rad)

        # 车辆中心
        center_x = self.x - camera_x
        center_y = self.y - camera_y

        # 根据车辆类型设置尺寸
        if self.car_type == "truck":
            width = CAR_WIDTH * 1.2
            height = CAR_HEIGHT * 1.5
        elif self.car_type == "formula":
            width = CAR_WIDTH * 0.8
            height = CAR_HEIGHT * 0.7
        else:  # sports
            width = CAR_WIDTH
            height = CAR_HEIGHT

        # 车辆顶点
        half_width = width / 2
        half_height = height / 2

        corners = [
            (-half_width, -half_height),
            (half_width, -half_height),
            (half_width, half_height),
            (-half_width, half_height)
        ]

        # 旋转顶点
        rotated = []
        for x, y in corners:
            rx = x * cos_a - y * sin_a
            ry = x * sin_a + y * cos_a
            rotated.append((center_x + rx, center_y + ry))

        # 绘制车辆主体
        car_color = self.color
        if self.invincible and pygame.time.get_ticks() % 200 < 100:
            car_color = WHITE

        pygame.draw.polygon(screen, car_color, rotated)

        # 绘制车窗
        window_color = (min(car_color[0] + 50, 255),
                        min(car_color[1] + 50, 255),
                        min(car_color[2] + 50, 255))
        window_corners = [
            (-half_width * 0.7, -half_height * 0.3),
            (half_width * 0.7, -half_height * 0.3),
            (half_width * 0.7, half_height * 0.2),
            (-half_width * 0.7, half_height * 0.2)
        ]

        window_rotated = []
        for x, y in window_corners:
            rx = x * cos_a - y * sin_a
            ry = x * sin_a + y * cos_a
            window_rotated.append((center_x + rx, center_y + ry))

        pygame.draw.polygon(screen, window_color, window_rotated)

        # 绘制车灯
        if pygame.time.get_ticks() % 1000 < 500:
            light_offset = half_height + 5
            front_x = center_x + math.cos(rad) * light_offset
            front_y = center_y + math.sin(rad) * light_offset
            pygame.draw.circle(screen, (255, 255, 200),
                               (int(front_x), int(front_y)), 8)

        # 绘制护盾
        if self.shield_active:
            shield_radius = max(width, height) * 0.7
            shield_alpha = int(
                150 + 105 * (math.sin(pygame.time.get_ticks() * 0.005) * 0.5 + 0.5))
            shield_surface = pygame.Surface(
                (int(shield_radius*2), int(shield_radius*2)), pygame.SRCALPHA)
            pygame.draw.circle(shield_surface, (*CYAN[:3], shield_alpha),
                               (int(shield_radius), int(shield_radius)), int(shield_radius), 4)
            screen.blit(shield_surface, (int(
                center_x - shield_radius), int(center_y - shield_radius)))

        # 绘制车辆编号
        if not self.is_player:
            number_color = WHITE if sum(car_color) < 380 else BLACK
            number_text = font_small.render(
                str(int(self.position)), True, number_color)
            screen.blit(number_text, (int(center_x - number_text.get_width()/2),
                                      int(center_y - number_text.get_height()/2)))

    def get_rect(self):
        return pygame.Rect(self.x - self.width/2, self.y - self.height/2,
                           self.width, self.height)

    def take_damage(self, amount):
        if not self.invincible and not self.shield_active:
            self.health = max(0, self.health - amount)
            self.invincible = True
            self.invincible_time = 60
            return True
        return False

    def collect_item(self, item_type):
        if item_type == "nitro":
            self.nitro = min(100, self.nitro + 30)
        elif item_type == "shield":
            self.shield_active = True
            self.shield = 300
        elif item_type == "turbo":
            self.turbo_active = True
            self.speed = min(self.speed + 3, self.max_speed)
        elif item_type == "repair":
            self.health = min(100, self.health + 30)
        elif item_type == "fuel":
            self.fuel = min(100, self.fuel + 40)
        return True


class Track:
    def __init__(self):
        self.width = TRACK_WIDTH
        self.points = []
        self.checkpoints = []
        self.walls = []
        self.generate_track()

    def generate_track(self):
        # 生成随机赛道
        num_points = TRACK_SEGMENTS
        center_x = SCREEN_WIDTH // 2
        center_y = SCREEN_HEIGHT // 2

        # 创建圆形赛道
        radius = random.randint(MIN_RADIUS, MAX_RADIUS)
        for i in range(num_points):
            angle = 2 * math.pi * i / num_points
            x = center_x + math.cos(angle) * radius
            y = center_y + math.sin(angle) * radius

            # 添加一些随机扰动
            if i > 0 and i < num_points - 1:
                x += random.randint(-50, 50)
                y += random.randint(-50, 50)

            self.points.append((x, y))

            # 创建检查点
            if i % 20 == 0:
                self.checkpoints.append({
                    'x': x,
                    'y': y,
                    'radius': CHECKPOINT_SIZE * 2
                })

        # 创建墙壁
        for i, (x, y) in enumerate(self.points):
            next_i = (i + 1) % len(self.points)
            next_x, next_y = self.points[next_i]

            # 内墙
            angle = math.atan2(next_y - y, next_x - x)
            perp_angle = angle + math.pi / 2

            inner_x1 = x + math.cos(perp_angle) * (self.width / 2 - 20)
            inner_y1 = y + math.sin(perp_angle) * (self.width / 2 - 20)
            inner_x2 = next_x + math.cos(perp_angle) * (self.width / 2 - 20)
            inner_y2 = next_y + math.sin(perp_angle) * (self.width / 2 - 20)

            # 外墙
            outer_x1 = x - math.cos(perp_angle) * (self.width / 2 - 20)
            outer_y1 = y - math.sin(perp_angle) * (self.width / 2 - 20)
            outer_x2 = next_x - math.cos(perp_angle) * (self.width / 2 - 20)
            outer_y2 = next_y - math.sin(perp_angle) * (self.width / 2 - 20)

            self.walls.append({
                'inner': (inner_x1, inner_y1, inner_x2, inner_y2),
                'outer': (outer_x1, outer_y1, outer_x2, outer_y2)
            })

    def draw(self, screen, camera_x, camera_y):
        # 绘制草地
        for x in range(0, SCREEN_WIDTH * 2, GRASS_PATTERN):
            for y in range(0, SCREEN_HEIGHT * 2, GRASS_PATTERN):
                screen_x = x - camera_x % GRASS_PATTERN
                screen_y = y - camera_y % GRASS_PATTERN
                color = GRASS_LIGHT if (
                    x // GRASS_PATTERN + y // GRASS_PATTERN) % 2 == 0 else GRASS_DARK
                pygame.draw.rect(
                    screen, color, (screen_x, screen_y, GRASS_PATTERN, GRASS_PATTERN))

        # 绘制赛道
        for wall in self.walls:
            # 绘制赛道表面
            inner_x1, inner_y1, inner_x2, inner_y2 = wall['inner']
            outer_x1, outer_y1, outer_x2, outer_y2 = wall['outer']

            points = [
                (inner_x1 - camera_x, inner_y1 - camera_y),
                (inner_x2 - camera_x, inner_y2 - camera_y),
                (outer_x2 - camera_x, outer_y2 - camera_y),
                (outer_x1 - camera_x, outer_y1 - camera_y)
            ]

            pygame.draw.polygon(screen, ROAD_COLOR, points)

            # 绘制赛道边缘
            pygame.draw.line(screen, WALL_COLOR,
                             (inner_x1 - camera_x, inner_y1 - camera_y),
                             (inner_x2 - camera_x, inner_y2 - camera_y), 5)
            pygame.draw.line(screen, WALL_COLOR,
                             (outer_x1 - camera_x, outer_y1 - camera_y),
                             (outer_x2 - camera_x, outer_y2 - camera_y), 5)

        # 绘制赛道线
        for i in range(len(self.points)):
            x1, y1 = self.points[i]
            x2, y2 = self.points[(i + 1) % len(self.points)]

            # 中心线
            pygame.draw.line(screen, LANE_COLOR,
                             (x1 - camera_x, y1 - camera_y),
                             (x2 - camera_x, y2 - camera_y), 3)

            # 网格线
            if i % 5 == 0:
                for j in range(5):
                    t = j / 5
                    grid_x = x1 + (x2 - x1) * t
                    grid_y = y1 + (y2 - y1) * t
                    pygame.draw.line(screen, GRID_COLOR,
                                     (grid_x - camera_x - 10, grid_y - camera_y),
                                     (grid_x - camera_x + 10, grid_y - camera_y), 2)

        # 绘制检查点
        for i, checkpoint in enumerate(self.checkpoints):
            x, y = checkpoint['x'], checkpoint['y']
            radius = checkpoint['radius']

            # 检查点标志
            color = GREEN if i % 2 == 0 else YELLOW
            pygame.draw.circle(screen, color,
                               (int(x - camera_x), int(y - camera_y)), radius, 3)

            # 检查点编号
            text = font_small.render(str(i+1), True, color)
            screen.blit(text, (int(x - camera_x - text.get_width()/2),
                               int(y - camera_y - text.get_height()/2)))

        # 绘制看台
        grandstand_x = SCREEN_WIDTH // 2 - camera_x
        grandstand_y = SCREEN_HEIGHT // 2 - GRANDSTAND_HEIGHT - camera_y
        pygame.draw.rect(screen, GRANDSTAND_COLOR,
                         (grandstand_x - GRANDSTAND_WIDTH//2, grandstand_y,
                          GRANDSTAND_WIDTH, GRANDSTAND_HEIGHT))

        # 绘制观众
        for i in range(20):
            cx = grandstand_x - GRANDSTAND_WIDTH//2 + 20 + (i % 5) * 40
            cy = grandstand_y + 30 + (i // 5) * 60
            pygame.draw.circle(screen, CROWD_COLOR,
                               (int(cx), int(cy)), CROWD_SIZE)

        # 绘制旗帜
        flag_x = grandstand_x
        flag_y = grandstand_y - 20
        pygame.draw.rect(screen, FLAG_COLOR,
                         (flag_x, flag_y, FLAG_WIDTH, FLAG_HEIGHT))
        pygame.draw.polygon(screen, RED,
                            [(flag_x + FLAG_WIDTH, flag_y),
                             (flag_x + FLAG_WIDTH + 50, flag_y + 20),
                                (flag_x + FLAG_WIDTH, flag_y + 40)])


class Item:
    def __init__(self, x, y, item_type):
        self.x = x
        self.y = y
        self.type = item_type
        self.collected = False
        self.rotation = 0
        self.float_offset = 0
        self.float_speed = random.uniform(0.05, 0.1)
        self.collect_time = 0

    def update(self):
        if not self.collected:
            self.rotation = (self.rotation + 2) % 360
            self.float_offset = math.sin(
                pygame.time.get_ticks() * self.float_speed) * 10
        elif self.collect_time > 0:
            self.collect_time -= 1

        return not self.collected or self.collect_time > 0

    def draw(self, screen, camera_x, camera_y):
        draw_x = self.x - camera_x
        draw_y = self.y - camera_y + self.float_offset

        if self.type == "nitro":
            # 氮气瓶
            pygame.draw.rect(screen, CYAN,
                             (draw_x - NITRO_SIZE//2, draw_y - NITRO_SIZE//2,
                              NITRO_SIZE, NITRO_SIZE), border_radius=5)
            pygame.draw.rect(screen, (0, 150, 200),
                             (draw_x - NITRO_SIZE//3, draw_y - NITRO_SIZE//2,
                              NITRO_SIZE*2//3, NITRO_SIZE//4), border_radius=3)
            text = font_small.render("N", True, WHITE)
            screen.blit(text, (int(draw_x - text.get_width()/2),
                               int(draw_y - text.get_height()/2)))

        elif self.type == "shield":
            # 护盾
            shield_surface = pygame.Surface(
                (SHIELD_SIZE*2, SHIELD_SIZE*2), pygame.SRCALPHA)
            pygame.draw.circle(shield_surface, (*BLUE[:3], 150),
                               (SHIELD_SIZE, SHIELD_SIZE), SHIELD_SIZE, 5)
            screen.blit(shield_surface, (int(draw_x - SHIELD_SIZE),
                        int(draw_y - SHIELD_SIZE)))
            text = font_small.render("S", True, WHITE)
            screen.blit(text, (int(draw_x - text.get_width()/2),
                               int(draw_y - text.get_height()/2)))

        elif self.type == "turbo":
            # 涡轮
            points = []
            for i in range(6):
                angle = math.radians(self.rotation + i * 60)
                px = draw_x + math.cos(angle) * TURBO_SIZE//2
                py = draw_y + math.sin(angle) * TURBO_SIZE//2
                points.append((px, py))
            pygame.draw.polygon(screen, ORANGE, points)
            text = font_small.render("T", True, WHITE)
            screen.blit(text, (int(draw_x - text.get_width()/2),
                               int(draw_y - text.get_height()/2)))

        elif self.type == "repair":
            # 维修包
            pygame.draw.rect(screen, GREEN,
                             (draw_x - ITEM_SIZE//2, draw_y - ITEM_SIZE//2,
                              ITEM_SIZE, ITEM_SIZE), border_radius=3)
            pygame.draw.line(screen, WHITE,
                             (draw_x - 8, draw_y), (draw_x + 8, draw_y), 3)
            pygame.draw.line(screen, WHITE,
                             (draw_x, draw_y - 8), (draw_x, draw_y + 8), 3)

        elif self.type == "fuel":
            # 燃料
            points = [
                (draw_x, draw_y - ITEM_SIZE//2),
                (draw_x + ITEM_SIZE//2, draw_y + ITEM_SIZE//2),
                (draw_x - ITEM_SIZE//2, draw_y + ITEM_SIZE//2)
            ]
            pygame.draw.polygon(screen, RED, points)

        elif self.type == "oil":
            # 油渍
            pygame.draw.circle(screen, (50, 50, 50, 150),
                               (int(draw_x), int(draw_y)), OIL_SIZE)

        elif self.type == "spike":
            # 钉子
            points = []
            for i in range(3):
                angle = math.radians(self.rotation + i * 120)
                px = draw_x + math.cos(angle) * SPIKE_SIZE
                py = draw_y + math.sin(angle) * SPIKE_SIZE
                points.append((px, py))
            pygame.draw.polygon(screen, RED, points)

    def get_rect(self):
        size = ITEM_SIZE
        if self.type == "oil":
            size = OIL_SIZE
        elif self.type == "spike":
            size = SPIKE_SIZE
        return pygame.Rect(self.x - size, self.y - size, size*2, size*2)

    def collect(self):
        if not self.collected:
            self.collected = True
            self.collect_time = 30
            return True
        return False


class RaceGame:
    def __init__(self):
        self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
        pygame.display.set_caption("2D赛车游戏")
        self.clock = pygame.time.Clock()

        # 游戏组件
        self.track = Track()
        self.cars = []
        self.items = []

        # 玩家车辆
        player_colors = [BLUE, RED, GREEN, YELLOW, PURPLE, ORANGE]
        player_car = Car(SCREEN_WIDTH//2, SCREEN_HEIGHT//2,
                         random.choice(player_colors), True, "sports")
        self.cars.append(player_car)
        self.player = player_car

        # AI车辆
        ai_colors = [RED, GREEN, YELLOW, PURPLE, ORANGE, CYAN, PINK]
        ai_types = ["sports", "truck", "formula"]
        for i in range(5):
            color = ai_colors[i % len(ai_colors)]
            car_type = ai_types[i % len(ai_types)]
            angle = 2 * math.pi * i / 5
            x = SCREEN_WIDTH//2 + math.cos(angle) * 100
            y = SCREEN_HEIGHT//2 + math.sin(angle) * 100
            ai_car = Car(x, y, color, False, car_type)
            ai_car.position = i + 2
            self.cars.append(ai_car)

        # 生成物品
        self._generate_items()

        # 游戏状态
        self.camera_x = 0
        self.camera_y = 0
        self.game_over = False
        self.paused = False
        self.race_started = False
        self.countdown = 3
        self.countdown_timer = 0
        self.total_laps = 3
        self.explosions = []
        self.race_time = 0
        self.start_time = 0

        # 音效
        self.engine_sound = None
        self.explosion_sound = None

    def _generate_items(self):
        # 在赛道上随机生成物品
        for _ in range(20):
            # 在赛道上找一个随机点
            point_idx = random.randint(0, len(self.track.points)-1)
            x, y = self.track.points[point_idx]

            # 随机偏移
            angle = random.uniform(0, 2 * math.pi)
            distance = random.uniform(50, self.track.width/2 - 50)
            item_x = x + math.cos(angle) * distance
            item_y = y + math.sin(angle) * distance

            # 随机物品类型
            item_types = ["nitro", "shield", "turbo",
                          "repair", "fuel", "oil", "spike"]
            weights = [3, 2, 2, 2, 3, 1, 1]
            item_type = random.choices(item_types, weights=weights)[0]

            self.items.append(Item(item_x, item_y, item_type))

    def update_camera(self):
        # 摄像机跟随玩家
        target_x = self.player.x - SCREEN_WIDTH // 2
        target_y = self.player.y - SCREEN_HEIGHT // 2

        # 平滑移动
        self.camera_x += (target_x - self.camera_x) * 0.1
        self.camera_y += (target_y - self.camera_y) * 0.1

    def update(self, keys, dt):
        if self.game_over or self.paused:
            return

        # 更新倒计时
        if not self.race_started:
            self.countdown_timer += dt
            if self.countdown_timer >= 1:
                self.countdown_timer = 0
                self.countdown -= 1
                if self.countdown <= 0:
                    self.race_started = True
                    self.start_time = time.time()
            return

        # 更新摄像机
        self.update_camera()

        # 更新比赛时间
        if self.race_started:
            self.race_time = time.time() - self.start_time

        # 更新车辆
        for car in self.cars:
            car.update(keys, self.track.points, self.cars, self.items, dt)

            # 检查墙壁碰撞
            for wall in self.track.walls:
                # 简单碰撞检测
                car_rect = car.get_rect()
                # 这里可以添加更精确的碰撞检测

            # 检查物品碰撞
            for item in self.items[:]:
                if not item.collected and car.get_rect().colliderect(item.get_rect()):
                    if item.collect():
                        car.collect_item(item.type)

                        # 如果是负面物品
                        if item.type == "oil":
                            car.on_oil = True
                            car.traction = 0.5
                        elif item.type == "spike":
                            car.on_spike = True
                            car.take_damage(20)

            # 检查车辆碰撞
            for other in self.cars:
                if car != other and car.get_rect().colliderect(other.get_rect()):
                    if car.take_damage(10) or other.take_damage(10):
                        # 创建爆炸效果
                        self.explosions.append({
                            'x': (car.x + other.x) / 2,
                            'y': (car.y + other.y) / 2,
                            'size': 30,
                            'max_size': 60,
                            'lifetime': 30
                        })

            # 检查检查点
            for i, checkpoint in enumerate(self.track.checkpoints):
                dist = math.sqrt(
                    (car.x - checkpoint['x'])**2 + (car.y - checkpoint['y'])**2)
                if dist < checkpoint['radius']:
                    if i == (car.checkpoint + 1) % len(self.track.checkpoints):
                        car.checkpoint = i
                        if i == 0:  # 完成一圈
                            car.lap += 1
                            current_time = self.race_time
                            lap_time = current_time - car.last_lap_time
                            if lap_time < car.best_lap:
                                car.best_lap = lap_time
                            car.last_lap_time = current_time

                            # 检查是否完成比赛
                            if car.lap >= self.total_laps:
                                if car.is_player:
                                    self.game_over = True

            # 检查车辆状态
            if car.health <= 0 or car.fuel <= 0:
                if car.is_player:
                    self.game_over = True

        # 更新物品
        for item in self.items[:]:
            if not item.update():
                self.items.remove(item)

        # 更新爆炸效果
        for explosion in self.explosions[:]:
            explosion['size'] += 2
            explosion['lifetime'] -= 1
            if explosion['lifetime'] <= 0:
                self.explosions.remove(explosion)

        # 更新排名
        self._update_positions()

    def _update_positions(self):
        # 根据进度排序车辆
        sorted_cars = sorted(
            self.cars, key=lambda c: (-c.lap, -c.checkpoint, c.race_time))
        for i, car in enumerate(sorted_cars):
            car.position = i + 1

    def draw(self):
        # 绘制天空
        self.screen.fill(SKY_COLOR)

        # 绘制赛道
        self.track.draw(self.screen, self.camera_x, self.camera_y)

        # 绘制物品
        for item in self.items:
            item.draw(self.screen, self.camera_x, self.camera_y)

        # 绘制车辆
        for car in self.cars:
            car.draw(self.screen, self.camera_x, self.camera_y)

        # 绘制爆炸效果
        for explosion in self.explosions:
            alpha = int(255 * (explosion['lifetime'] / 30))
            size = explosion['size']
            temp_surface = pygame.Surface((size*2, size*2), pygame.SRCALPHA)
            pygame.draw.circle(
                temp_surface, (255, 100, 0, alpha), (size, size), size)
            pygame.draw.circle(
                temp_surface, (255, 200, 0, alpha), (size, size), size//2)
            self.screen.blit(temp_surface,
                             (int(explosion['x'] - self.camera_x - size),
                              int(explosion['y'] - self.camera_y - size)))

        # 绘制UI
        self.draw_ui()

        # 绘制倒计时
        if not self.race_started:
            self.draw_countdown()

        # 绘制游戏结束画面
        if self.game_over:
            self.draw_game_over()

        # 绘制暂停画面
        if self.paused:
            self.draw_pause_screen()

        pygame.display.flip()

    def draw_ui(self):
        # 绘制半透明面板
        panel = pygame.Surface((SCREEN_WIDTH, 120), pygame.SRCALPHA)
        panel.fill((0, 0, 0, 150))
        self.screen.blit(panel, (0, 0))
        self.screen.blit(panel, (0, SCREEN_HEIGHT - 120))

        # 左上角：比赛信息
        time_text = font_medium.render(
            f"时间: {self.race_time:.1f}s", True, WHITE)
        self.screen.blit(time_text, (20, 20))

        lap_text = font_medium.render(
            f"圈数: {self.player.lap}/{self.total_laps}", True, WHITE)
        self.screen.blit(lap_text, (20, 55))

        pos_text = font_medium.render(
            f"位置: {self.player.position}/{len(self.cars)}", True, WHITE)
        self.screen.blit(pos_text, (250, 20))

        checkpoint_text = font_medium.render(
            f"检查点: {self.player.checkpoint+1}/{len(self.track.checkpoints)}", True, WHITE)
        self.screen.blit(checkpoint_text, (250, 55))

        # 右上角：车辆状态
        health_width = 200
        health_height = 20
        health_x = SCREEN_WIDTH - 250
        health_y = 20

        pygame.draw.rect(self.screen, DARK_GRAY, (health_x,
                         health_y, health_width, health_height))
        health_fill = health_width * (self.player.health / 100)
        health_color = (
            int(255 * (1 - self.player.health/100)),
            int(255 * (self.player.health/100)),
            0
        )
        pygame.draw.rect(self.screen, health_color, (health_x,
                         health_y, health_fill, health_height))
        pygame.draw.rect(self.screen, WHITE, (health_x,
                         health_y, health_width, health_height), 2)

        fuel_x = SCREEN_WIDTH - 250
        fuel_y = 55

        pygame.draw.rect(self.screen, DARK_GRAY,
                         (fuel_x, fuel_y, health_width, health_height))
        fuel_fill = health_width * (self.player.fuel / 100)
        pygame.draw.rect(self.screen, RED,
                         (fuel_x, fuel_y, fuel_fill, health_height))
        pygame.draw.rect(self.screen, WHITE, (fuel_x, fuel_y,
                         health_width, health_height), 2)

        nitro_x = SCREEN_WIDTH - 250
        nitro_y = 90

        pygame.draw.rect(self.screen, DARK_GRAY,
                         (nitro_x, nitro_y, health_width, health_height))
        nitro_fill = health_width * (self.player.nitro / 100)
        pygame.draw.rect(self.screen, CYAN,
                         (nitro_x, nitro_y, nitro_fill, health_height))
        pygame.draw.rect(self.screen, WHITE, (nitro_x, nitro_y,
                         health_width, health_height), 2)

        # 底部：排名表
        rank_y = SCREEN_HEIGHT - 110
        for i, car in enumerate(sorted(self.cars, key=lambda c: c.position)[:5]):
            rank_x = 20
            rank_color = car.color
            if car.is_player:
                rank_color = YELLOW

            # 排名编号
            rank_text = font_small.render(f"{car.position}.", True, rank_color)
            self.screen.blit(rank_text, (rank_x, rank_y + i * 20))

            # 车辆类型图标
            type_icon = "🏎️" if car.car_type == "sports" else "🚚" if car.car_type == "truck" else "🏁"
            type_text = font_small.render(type_icon, True, rank_color)
            self.screen.blit(type_text, (rank_x + 40, rank_y + i * 20))

            # 圈数
            lap_text = font_small.render(
                f"Lap: {car.lap}/{self.total_laps}", True, rank_color)
            self.screen.blit(lap_text, (rank_x + 80, rank_y + i * 20))

            # 时间
            if car.is_player or car.lap > 0:
                time_str = f"{car.best_lap:.1f}s" if car.best_lap < 999999 else "--"
                time_text = font_small.render(
                    f"Best: {time_str}", True, rank_color)
                self.screen.blit(time_text, (rank_x + 180, rank_y + i * 20))

        # 控制说明
        controls = [
            "WASD/方向键: 驾驶",
            "空格键: 氮气加速",
            "P: 暂停/继续",
            "R: 重新开始",
            "ESC: 退出"
        ]

        for i, text in enumerate(controls):
            control_text = font_small.render(text, True, YELLOW)
            self.screen.blit(control_text, (SCREEN_WIDTH -
                             200, SCREEN_HEIGHT - 110 + i * 20))

    def draw_countdown(self):
        overlay = pygame.Surface(
            (SCREEN_WIDTH, SCREEN_HEIGHT), pygame.SRCALPHA)
        overlay.fill((0, 0, 0, 100))
        self.screen.blit(overlay, (0, 0))

        if self.countdown > 0:
            count_text = font_large.render(str(self.countdown), True, YELLOW)
        else:
            count_text = font_large.render("GO!", True, GREEN)

        self.screen.blit(count_text,
                         (SCREEN_WIDTH//2 - count_text.get_width()//2,
                          SCREEN_HEIGHT//2 - count_text.get_height()//2))

    def draw_game_over(self):
        overlay = pygame.Surface(
            (SCREEN_WIDTH, SCREEN_HEIGHT), pygame.SRCALPHA)
        overlay.fill((0, 0, 0, 200))
        self.screen.blit(overlay, (0, 0))

        if self.player.lap >= self.total_laps:
            result_text = font_large.render("比赛完成!", True, GREEN)
        else:
            result_text = font_large.render("比赛结束", True, RED)

        self.screen.blit(result_text,
                         (SCREEN_WIDTH//2 - result_text.get_width()//2,
                          SCREEN_HEIGHT//2 - 100))

        time_text = font_medium.render(
            f"比赛时间: {self.race_time:.2f}s", True, YELLOW)
        self.screen.blit(time_text,
                         (SCREEN_WIDTH//2 - time_text.get_width()//2,
                          SCREEN_HEIGHT//2 - 30))

        pos_text = font_medium.render(
            f"最终排名: 第{self.player.position}名", True, YELLOW)
        self.screen.blit(pos_text,
                         (SCREEN_WIDTH//2 - pos_text.get_width()//2,
                          SCREEN_HEIGHT//2))

        best_text = font_medium.render(
            f"最快圈速: {self.player.best_lap:.2f}s", True, YELLOW)
        self.screen.blit(best_text,
                         (SCREEN_WIDTH//2 - best_text.get_width()//2,
                          SCREEN_HEIGHT//2 + 30))

        restart_text = font_medium.render("按R键重新开始，ESC键退出", True, WHITE)
        self.screen.blit(restart_text,
                         (SCREEN_WIDTH//2 - restart_text.get_width()//2,
                          SCREEN_HEIGHT//2 + 100))

    def draw_pause_screen(self):
        overlay = pygame.Surface(
            (SCREEN_WIDTH, SCREEN_HEIGHT), pygame.SRCALPHA)
        overlay.fill((0, 0, 0, 150))
        self.screen.blit(overlay, (0, 0))

        paused_text = font_large.render("游戏暂停", True, YELLOW)
        self.screen.blit(paused_text,
                         (SCREEN_WIDTH//2 - paused_text.get_width()//2,
                          SCREEN_HEIGHT//2 - 50))

        continue_text = font_medium.render("按P键继续游戏", True, WHITE)
        self.screen.blit(continue_text,
                         (SCREEN_WIDTH//2 - continue_text.get_width()//2,
                          SCREEN_HEIGHT//2 + 20))

    def reset(self):
        self.__init__()


def main():
    game = RaceGame()
    running = True

    while running:
        dt = game.clock.tick(FPS) / 1000.0

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    running = False
                elif event.key == pygame.K_p:
                    game.paused = not game.paused
                elif event.key == pygame.K_r and game.game_over:
                    game.reset()

        keys = pygame.key.get_pressed()

        if not game.paused:
            game.update(keys, dt)

        game.draw()

    pygame.quit()
    sys.exit()


if __name__ == "__main__":
    main()
