import pygame
import random
import sys
import math

# 初始化pygame
pygame.init()

# 游戏常量
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
FPS = 60
ROAD_WIDTH = 400
LANE_WIDTH = ROAD_WIDTH // 3
CAR_WIDTH = 40
CAR_HEIGHT = 70
OBSTACLE_WIDTH = 50
OBSTACLE_HEIGHT = 50
SPEED = 5
MIN_OBSTACLE_DISTANCE = 150

# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GRAY = (100, 100, 100)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 100, 255)
YELLOW = (255, 255, 0)
ORANGE = (255, 165, 0)
ROAD_COLOR = (50, 50, 50)
GRASS_COLOR = (0, 150, 0)
LINE_COLOR = (255, 255, 255)
SKY_COLOR = (135, 206, 235)
WHEEL_COLOR = (30, 30, 30)
WINDOW_COLOR = (200, 230, 255)


def draw_rounded_rect_manual(surface, color, rect, radius=0):
    """手动绘制圆角矩形的兼容函数"""
    x, y, width, height = rect
    if radius <= 0:
        pygame.draw.rect(surface, color, rect)
    else:
        # 绘制四个角的圆角
        pygame.draw.circle(surface, color, (x + radius, y + radius), radius)
        pygame.draw.circle(
            surface, color, (x + width - radius, y + radius), radius)
        pygame.draw.circle(surface, color, (x + radius,
                           y + height - radius), radius)
        pygame.draw.circle(surface, color, (x + width -
                           radius, y + height - radius), radius)

        # 绘制中间的矩形部分
        pygame.draw.rect(surface, color, (x + radius,
                         y, width - 2*radius, height))
        pygame.draw.rect(
            surface, color, (x, y + radius, width, height - 2*radius))


class Car:
    """玩家控制的汽车"""

    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.width = CAR_WIDTH
        self.height = CAR_HEIGHT
        self.speed = 0
        self.max_speed = 8
        self.acceleration = 0.2
        self.deceleration = 0.3
        self.lane = 1  # 0=左车道, 1=中车道, 2=右车道
        self.score = 0

    def update(self, keys):
        """更新汽车状态"""
        # 加速和减速
        if keys[pygame.K_UP] or keys[pygame.K_w]:
            self.speed = min(self.speed + self.acceleration, self.max_speed)
        elif keys[pygame.K_DOWN] or keys[pygame.K_s]:
            self.speed = max(self.speed - self.deceleration, 0)
        else:
            # 缓慢减速
            self.speed = max(self.speed - 0.1, 0)

        # 左右移动（换车道）
        if keys[pygame.K_LEFT] or keys[pygame.K_a]:
            self.move_left()
        if keys[pygame.K_RIGHT] or keys[pygame.K_d]:
            self.move_right()

        # 计算车道中心位置
        road_left = (SCREEN_WIDTH - ROAD_WIDTH) // 2
        target_x = road_left + self.lane * \
            LANE_WIDTH + (LANE_WIDTH - self.width) // 2

        # 平滑移动
        self.x += (target_x - self.x) * 0.3

    def move_left(self):
        """向左换车道"""
        if self.lane > 0:
            self.lane -= 1

    def move_right(self):
        """向右换车道"""
        if self.lane < 2:
            self.lane += 1

    def get_rect(self):
        """获取汽车的矩形区域（用于碰撞检测）"""
        return pygame.Rect(self.x, self.y, self.width, self.height)

    def draw(self, surface):
        """绘制汽车"""
        # 汽车主体 - 使用普通矩形
        car_body = pygame.Rect(self.x, self.y, self.width, self.height)
        pygame.draw.rect(surface, BLUE, car_body)

        # 添加一些装饰线条让汽车看起来更立体
        # 车顶
        pygame.draw.rect(surface, (0, 80, 160),
                         (self.x, self.y, self.width, 10))
        # 车身装饰线
        pygame.draw.line(surface, (0, 150, 255), (self.x,
                         self.y + 15), (self.x + self.width, self.y + 15), 2)

        # 车窗
        window_rect = pygame.Rect(self.x + 5, self.y + 5, self.width - 10, 20)
        pygame.draw.rect(surface, WINDOW_COLOR, window_rect)
        pygame.draw.rect(surface, (150, 200, 255), window_rect, 1)  # 边框

        # 车灯
        pygame.draw.rect(surface, YELLOW, (self.x, self.y, 5, 5))
        pygame.draw.rect(surface, YELLOW, (self.x +
                         self.width - 5, self.y, 5, 5))

        # 车轮
        # 前轮
        pygame.draw.rect(surface, WHEEL_COLOR,
                         (self.x - 3, self.y + 20, 6, 10))
        pygame.draw.rect(surface, WHEEL_COLOR, (self.x +
                         self.width - 3, self.y + 20, 6, 10))
        # 后轮
        pygame.draw.rect(surface, WHEEL_COLOR, (self.x - 3,
                         self.y + self.height - 20, 6, 10))
        pygame.draw.rect(surface, WHEEL_COLOR, (self.x +
                         self.width - 3, self.y + self.height - 20, 6, 10))


class Obstacle:
    """障碍物"""

    def __init__(self, x, y, obstacle_type="car"):
        self.x = x
        self.y = y
        self.width = OBSTACLE_WIDTH
        self.height = OBSTACLE_HEIGHT
        self.speed = 3
        self.type = obstacle_type
        self.color = random.choice([RED, GREEN, ORANGE])

    def update(self, car_speed=0):
        """更新障碍物位置"""
        self.y += self.speed + car_speed * 0.5

    def is_off_screen(self):
        """检查障碍物是否离开屏幕"""
        return self.y > SCREEN_HEIGHT

    def get_rect(self):
        """获取障碍物的矩形区域"""
        return pygame.Rect(self.x, self.y, self.width, self.height)

    def draw(self, surface):
        """绘制障碍物"""
        if self.type == "car":
            # 绘制障碍车
            car_rect = pygame.Rect(self.x, self.y, self.width, self.height)
            pygame.draw.rect(surface, self.color, car_rect)

            # 车窗
            window_rect = pygame.Rect(
                self.x + 5, self.y + 5, self.width - 10, 15)
            pygame.draw.rect(surface, WINDOW_COLOR, window_rect)

            # 车灯
            pygame.draw.rect(surface, YELLOW, (self.x, self.y, 5, 5))
            pygame.draw.rect(surface, YELLOW, (self.x +
                             self.width - 5, self.y, 5, 5))
        else:
            # 绘制锥桶
            # 锥桶柱
            pygame.draw.rect(surface, ORANGE, (self.x +
                             self.width//2 - 5, self.y, 10, self.height//3))
            # 锥桶底座
            base_rect = pygame.Rect(
                self.x, self.y + self.height//3, self.width, self.height//3)
            pygame.draw.rect(surface, ORANGE, base_rect)


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)

        # 游戏对象
        road_left = (SCREEN_WIDTH - ROAD_WIDTH) // 2
        car_x = road_left + LANE_WIDTH + (LANE_WIDTH - CAR_WIDTH) // 2
        self.car = Car(car_x, SCREEN_HEIGHT - 150)

        # 游戏状态
        self.obstacles = []
        self.game_over = False
        self.score = 0
        self.high_score = 0
        self.obstacle_timer = 0
        self.obstacle_frequency = 60  # 每60帧生成一个障碍物

        # 道路标记
        self.road_markings = []
        self.create_road_markings()

    def create_road_markings(self):
        """创建道路标记"""
        road_left = (SCREEN_WIDTH - ROAD_WIDTH) // 2
        marking_spacing = 60
        marking_width = 20
        marking_height = 10

        for y in range(-marking_spacing, SCREEN_HEIGHT + marking_spacing, marking_spacing):
            x = road_left + LANE_WIDTH
            self.road_markings.append({
                'x': x - marking_width//2,
                'y': y,
                'width': marking_width,
                'height': marking_height
            })

            x = road_left + LANE_WIDTH * 2
            self.road_markings.append({
                'x': x - marking_width//2,
                'y': y,
                'width': marking_width,
                'height': marking_height
            })

    def update_road_markings(self, speed):
        """更新道路标记位置"""
        for marking in self.road_markings:
            marking['y'] += speed

            # 如果标记离开屏幕，重新放置到顶部
            if marking['y'] > SCREEN_HEIGHT:
                marking['y'] = -60

    def spawn_obstacle(self):
        """生成新的障碍物"""
        if random.random() < 0.3:  # 30%的概率生成
            road_left = (SCREEN_WIDTH - ROAD_WIDTH) // 2
            lane = random.randint(0, 2)
            x = road_left + lane * LANE_WIDTH + \
                (LANE_WIDTH - OBSTACLE_WIDTH) // 2

            # 检查是否与现有障碍物距离太近
            too_close = False
            for obstacle in self.obstacles:
                if abs(obstacle.y - (-OBSTACLE_HEIGHT)) < MIN_OBSTACLE_DISTANCE:
                    too_close = True
                    break

            if not too_close:
                obstacle_type = random.choice(["car", "cone"])
                new_obstacle = Obstacle(x, -OBSTACLE_HEIGHT, obstacle_type)
                self.obstacles.append(new_obstacle)

    def check_collision(self):
        """检查碰撞"""
        car_rect = self.car.get_rect()

        for obstacle in self.obstacles:
            if car_rect.colliderect(obstacle.get_rect()):
                return True

        return False

    def update(self):
        """更新游戏状态"""
        if not self.game_over:
            # 处理输入
            keys = pygame.key.get_pressed()
            self.car.update(keys)

            # 更新道路标记
            self.update_road_markings(self.car.speed)

            # 生成障碍物
            self.obstacle_timer += 1
            if self.obstacle_timer >= self.obstacle_frequency:
                self.spawn_obstacle()
                self.obstacle_timer = 0

            # 更新障碍物
            for obstacle in self.obstacles[:]:
                obstacle.update(self.car.speed)
                if obstacle.is_off_screen():
                    self.obstacles.remove(obstacle)
                    self.score += 10

            # 检查碰撞
            if self.check_collision():
                self.game_over = True
                if self.score > self.high_score:
                    self.high_score = self.score

    def handle_events(self):
        """处理事件"""
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return False
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    return False
                elif event.key == pygame.K_r and self.game_over:
                    # 重新开始游戏
                    road_left = (SCREEN_WIDTH - ROAD_WIDTH) // 2
                    car_x = road_left + LANE_WIDTH + \
                        (LANE_WIDTH - CAR_WIDTH) // 2
                    self.car = Car(car_x, SCREEN_HEIGHT - 150)
                    self.obstacles = []
                    self.game_over = False
                    self.score = 0
                    self.obstacle_timer = 0
                elif event.key == pygame.K_SPACE and not self.game_over:
                    # 加速
                    self.car.speed = min(
                        self.car.speed + 2, self.car.max_speed)

        return True

    def draw_background(self):
        """绘制背景"""
        # 天空
        self.screen.fill(SKY_COLOR)

        # 远山
        for i in range(3):
            height = 100 + i * 20
            color = (100 - i*20, 120 - i*20, 80 - i*10)
            pygame.draw.rect(self.screen, color,
                             (0, SCREEN_HEIGHT - height - i*30, SCREEN_WIDTH, height))

        # 草地
        grass_rect = pygame.Rect(0, SCREEN_HEIGHT - 50, SCREEN_WIDTH, 50)
        pygame.draw.rect(self.screen, GRASS_COLOR, grass_rect)

    def draw_road(self):
        """绘制道路"""
        road_left = (SCREEN_WIDTH - ROAD_WIDTH) // 2
        road_rect = pygame.Rect(road_left, 0, ROAD_WIDTH, SCREEN_HEIGHT)

        # 道路
        pygame.draw.rect(self.screen, ROAD_COLOR, road_rect)

        # 道路边缘线
        pygame.draw.rect(self.screen, WHITE,
                         (road_left - 5, 0, 5, SCREEN_HEIGHT))
        pygame.draw.rect(self.screen, WHITE, (road_left +
                         ROAD_WIDTH, 0, 5, SCREEN_HEIGHT))

        # 道路中线
        for marking in self.road_markings:
            pygame.draw.rect(self.screen, LINE_COLOR,
                             (marking['x'], marking['y'],
                              marking['width'], marking['height']))

        # 车道线（虚线）
        for i in range(1, 3):
            x = road_left + i * LANE_WIDTH
            for y in range(0, SCREEN_HEIGHT, 40):
                if y % 80 < 40:  # 虚线
                    pygame.draw.line(self.screen, WHITE,
                                     (x, y), (x, y + 20), 2)

    def draw_ui(self):
        """绘制UI"""
        # 速度表
        speed_text = self.font.render(
            f"速度: {int(self.car.speed * 10)}", True, YELLOW)
        self.screen.blit(speed_text, (20, 20))

        # 分数
        score_text = self.font.render(f"分数: {self.score}", True, YELLOW)
        self.screen.blit(score_text, (20, 60))

        # 最高分
        high_score_text = self.small_font.render(
            f"最高分: {self.high_score}", True, YELLOW)
        self.screen.blit(high_score_text, (20, 100))

        # 控制说明
        controls = [
            "方向键/WASD: 驾驶",
            "空格: 加速",
            "R: 重新开始",
            "ESC: 退出"
        ]

        for i, text in enumerate(controls):
            control_text = self.small_font.render(text, True, WHITE)
            self.screen.blit(control_text, (SCREEN_WIDTH - 150, 20 + i * 30))

        # 游戏结束提示
        if self.game_over:
            # 半透明覆盖
            overlay = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT))
            overlay.set_alpha(180)
            overlay.fill(BLACK)
            self.screen.blit(overlay, (0, 0))

            # 游戏结束文字
            game_over_text = self.font.render("游戏结束!", True, RED)
            score_text = self.font.render(f"最终分数: {self.score}", True, YELLOW)
            restart_text = self.small_font.render("按 R 键重新开始", True, WHITE)

            self.screen.blit(game_over_text,
                             (SCREEN_WIDTH//2 - game_over_text.get_width()//2,
                              SCREEN_HEIGHT//2 - 50))
            self.screen.blit(score_text,
                             (SCREEN_WIDTH//2 - score_text.get_width()//2,
                              SCREEN_HEIGHT//2))
            self.screen.blit(restart_text,
                             (SCREEN_WIDTH//2 - restart_text.get_width()//2,
                              SCREEN_HEIGHT//2 + 50))

    def draw(self):
        """绘制游戏"""
        self.draw_background()
        self.draw_road()

        # 绘制障碍物
        for obstacle in self.obstacles:
            obstacle.draw(self.screen)

        # 绘制玩家汽车
        self.car.draw(self.screen)

        # 绘制UI
        self.draw_ui()

    def run(self):
        """运行游戏主循环"""
        running = True
        while running:
            running = self.handle_events()
            self.update()
            self.draw()
            pygame.display.flip()
            self.clock.tick(FPS)

        pygame.quit()
        sys.exit()


# 启动游戏
if __name__ == "__main__":
    try:
        game = Game()
        game.run()
    except Exception as e:
        print(f"游戏运行出错: {e}")
        import traceback
        traceback.print_exc()
        input("按Enter键退出...")
