import pygame
import math
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)
GRAY = (128, 128, 128)
YELLOW = (255, 255, 0)


class Car:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.angle = 0  # 车头朝向角度（度）
        self.speed = 0
        self.max_speed = 8
        self.acceleration = 0.2
        self.friction = 0.05
        self.turn_speed = 4
        self.width = 30
        self.height = 15

    def update(self, keys_pressed):
        # 处理输入
        if keys_pressed[pygame.K_UP]:
            self.speed += self.acceleration
        elif keys_pressed[pygame.K_DOWN]:
            self.speed -= self.acceleration
        else:
            # 应用摩擦力
            if self.speed > 0:
                self.speed = max(0, self.speed - self.friction)
            elif self.speed < 0:
                self.speed = min(0, self.speed + self.friction)

        # 限制速度
        self.speed = max(-self.max_speed/2, min(self.max_speed, self.speed))

        # 转向
        if keys_pressed[pygame.K_LEFT]:
            self.angle -= self.turn_speed * (abs(self.speed) / self.max_speed)
        if keys_pressed[pygame.K_RIGHT]:
            self.angle += self.turn_speed * (abs(self.speed) / self.max_speed)

        # 更新位置
        rad_angle = math.radians(self.angle)
        self.x += math.cos(rad_angle) * self.speed
        self.y += math.sin(rad_angle) * self.speed

        # 边界检测
        self.x = max(0, min(SCREEN_WIDTH - self.width, self.x))
        self.y = max(0, min(SCREEN_HEIGHT - self.height, self.y))

    def draw(self, screen):
        # 创建车的表面
        car_surface = pygame.Surface(
            (self.width, self.height), pygame.SRCALPHA)
        pygame.draw.rect(car_surface, RED, (0, 0, self.width, self.height))
        pygame.draw.rect(car_surface, BLACK,
                         (0, 0, self.width, self.height), 2)

        # 在车头画一个小三角形表示方向
        pygame.draw.polygon(car_surface, YELLOW, [
            (self.width - 2, self.height//2),
            (self.width - 8, self.height//2 - 3),
            (self.width - 8, self.height//2 + 3)
        ])

        # 旋转车
        rotated_car = pygame.transform.rotate(car_surface, -self.angle)
        rotated_rect = rotated_car.get_rect(
            center=(self.x + self.width//2, self.y + self.height//2))

        screen.blit(rotated_car, rotated_rect.topleft)

    def get_rect(self):
        return pygame.Rect(self.x, self.y, self.width, self.height)


class Track:
    def __init__(self):
        # 定义赛道边界（简单矩形赛道）
        self.outer_track = [
            (50, 50), (750, 50), (750, 550), (50, 550)
        ]
        self.inner_track = [
            (150, 150), (650, 150), (650, 450), (150, 450)
        ]
        self.checkpoints = [
            [(400, 50), (400, 150)],   # 上
            [(750, 300), (650, 300)],  # 右
            [(400, 550), (400, 450)],  # 下
            [(50, 300), (150, 300)]    # 左
        ]
        self.current_checkpoint = 0
        self.lap_count = 0

    def draw(self, screen):
        # 绘制外赛道
        pygame.draw.lines(screen, WHITE, True, self.outer_track, 3)
        # 绘制内赛道
        pygame.draw.lines(screen, WHITE, True, self.inner_track, 3)

        # 绘制检查点（当前激活的检查点用绿色，其他用灰色）
        for i, checkpoint in enumerate(self.checkpoints):
            color = GREEN if i == self.current_checkpoint else GRAY
            pygame.draw.line(screen, color, checkpoint[0], checkpoint[1], 2)

    def is_on_track(self, car_x, car_y):
        # 简单的赛道检测：检查是否在内外赛道之间
        # 这里使用简单的矩形检测作为示例
        outer_rect = pygame.Rect(50, 50, 700, 500)
        inner_rect = pygame.Rect(150, 150, 500, 300)

        car_rect = pygame.Rect(car_x, car_y, 30, 15)

        # 如果在外部赛道内且不在内部赛道内，则在赛道上
        on_outer = outer_rect.collidepoint(car_x + 15, car_y + 7.5)
        on_inner = inner_rect.collidepoint(car_x + 15, car_y + 7.5)

        return on_outer and not on_inner

    def check_checkpoint(self, car_x, car_y):
        # 检查是否通过当前检查点
        checkpoint = self.checkpoints[self.current_checkpoint]
        start, end = checkpoint

        # 创建检查点线段
        checkpoint_line = pygame.Rect(
            min(start[0], end[0]) - 5,
            min(start[1], end[1]) - 5,
            abs(start[0] - end[0]) + 10,
            abs(start[1] - end[1]) + 10
        )

        car_center_x = car_x + 15
        car_center_y = car_y + 7.5

        if checkpoint_line.collidepoint(car_center_x, car_center_y):
            self.current_checkpoint = (
                self.current_checkpoint + 1) % len(self.checkpoints)
            if self.current_checkpoint == 0:
                self.lap_count += 1
            return True
        return False


def main():
    screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
    pygame.display.set_caption("2D 赛车游戏")
    clock = pygame.time.Clock()

    # 创建游戏对象
    car = Car(400, 300)
    track = Track()

    # 游戏主循环
    running = True
    while running:
        # 处理事件
        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

        # 获取按键状态
        keys_pressed = pygame.key.get_pressed()

        # 更新游戏状态
        car.update(keys_pressed)

        # 检查是否在赛道上
        on_track = track.is_on_track(car.x, car.y)
        if not on_track:
            car.speed *= 0.8  # 减速

        # 检查检查点
        track.check_checkpoint(car.x, car.y)

        # 绘制
        screen.fill(BLACK)

        # 绘制赛道
        track.draw(screen)

        # 绘制赛车
        car.draw(screen)

        # 绘制UI信息
        font = pygame.font.Font(None, 36)
        speed_text = font.render(f"速度: {abs(car.speed):.1f}", True, WHITE)
        lap_text = font.render(f"圈数: {track.lap_count}", True, WHITE)
        checkpoint_text = font.render(
            f"检查点: {track.current_checkpoint + 1}/4", True, WHITE)

        screen.blit(speed_text, (10, 10))
        screen.blit(lap_text, (10, 50))
        screen.blit(checkpoint_text, (10, 90))

        if not on_track:
            off_track_text = font.render("离开赛道！", True, RED)
            screen.blit(off_track_text, (SCREEN_WIDTH // 2 - 80, 10))

        # 控制说明
        controls_font = pygame.font.Font(None, 24)
        controls = [
            "控制说明:",
            "↑ - 加速",
            "↓ - 刹车/倒车",
            "← → - 转向",
            "ESC - 退出"
        ]
        for i, text in enumerate(controls):
            control_text = controls_font.render(text, True, WHITE)
            screen.blit(control_text, (SCREEN_WIDTH - 180, 10 + i * 25))

        pygame.display.flip()
        clock.tick(FPS)

    pygame.quit()
    sys.exit()


if __name__ == "__main__":
    main()
