import pygame
import sys
import random

# 初始化
pygame.init()
WIDTH, HEIGHT = 900, 700
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("2D俯视角赛车游戏")
clock = pygame.time.Clock()
FPS = 60

# 颜色常量
GRASS = (40, 120, 30)
ROAD_GRAY = (65, 65, 65)
WHITE = (255, 255, 255)
YELLOW_LINE = (255, 210, 0)
RED_CAR = (220, 20, 20)
BLUE_CAR = (20, 80, 220)
BLACK_UI = (15, 15, 15)
GREEN_HP = (0, 220, 0)
RED_HP = (220, 0, 0)

# 赛道设置
ROAD_W = 420
road_x_left = (WIDTH - ROAD_W) // 2
road_x_right = road_x_left + ROAD_W
line_move_speed = 8
road_mark_list = []
# 初始化道路虚线
for y_pos in range(-HEIGHT, HEIGHT * 2, 90):
    road_mark_list.append(y_pos)

# 字体容错方案（解决你之前的报错）
try:
    font_info = pygame.font.SysFont("msyh", 22)
    font_big = pygame.font.SysFont("msyh", 26)
except:
    try:
        font_info = pygame.font.SysFont("simhei", 22)
        font_big = pygame.font.SysFont("simhei", 26)
    except:
        font_info = pygame.font.Font(None, 22)
        font_big = pygame.font.Font(None, 26)

# 玩家赛车类
class PlayerCar:
    def __init__(self):
        self.w = 36
        self.h = 65
        self.x = WIDTH // 2 - self.w//2
        self.y = HEIGHT - 150
        self.vx = 0
        self.vy = 0
        self.max_forward = 9
        self.max_back = -4
        self.acc = 0.35
        self.friction = 0.93
        self.hp = 100
        self.collide_flash = 0  # 碰撞闪烁标记

    def update(self, key_press):
        # 油门刹车
        if key_press[pygame.K_UP]:
            self.vy -= self.acc
        if key_press[pygame.K_DOWN]:
            self.vy += self.acc
        # 左右转向
        if key_press[pygame.K_LEFT]:
            self.vx -= self.acc
        if key_press[pygame.K_RIGHT]:
            self.vx += self.acc

        # 摩擦力
        self.vx *= self.friction
        self.vy *= self.friction

        # 速度限制
        self.vy = max(self.max_back, min(self.vy, self.max_forward))
        self.vx = max(-5, min(self.vx, 5))

        # 坐标更新
        self.x += self.vx
        self.y += self.vy

        # 赛道边界碰撞阻挡
        if self.x < road_x_left:
            self.x = road_x_left
            self.vx *= 0.4
            self.get_damage(0.3)
        if self.x + self.w > road_x_right:
            self.x = road_x_right - self.w
            self.vx *= 0.4
            self.get_damage(0.3)

        # 屏幕上下边界
        self.y = max(0, min(self.y, HEIGHT - self.h))

        # 碰撞闪烁计时
        if self.collide_flash > 0:
            self.collide_flash -= 1

    def get_damage(self, val):
        self.hp = max(0, self.hp - val)
        self.collide_flash = 8

    def draw(self):
        color = RED_CAR if self.collide_flash <= 0 else (255, 100, 100)
        rect = pygame.Rect(self.x, self.y, self.w, self.h)
        pygame.draw.rect(screen, color, rect, border_radius=7)
        # 车窗
        win_rect = pygame.Rect(self.x+5, self.y+10, self.w-10, 20)
        pygame.draw.rect(screen, (80, 150, 255), win_rect, border_radius=3)

# AI敌方车辆
class AICar:
    def __init__(self):
        self.w = 34
        self.h = 60
        self.x = random.randint(road_x_left + 10, road_x_right - self.w - 10)
        self.y = random.randint(-200, -80)
        self.speed = random.uniform(3, 6)

    def update(self):
        self.y += self.speed
        if self.y > HEIGHT + 50:
            self.reset()

    def reset(self):
        self.x = random.randint(road_x_left + 10, road_x_right - self.w - 10)
        self.y = random.randint(-300, -80)
        self.speed = random.uniform(3, 6)

    def draw(self):
        pygame.draw.rect(screen, BLUE_CAR, (self.x, self.y, self.w, self.h), border_radius=6)

# 碰撞检测函数
def rect_collision(car1, car2):
    r1 = pygame.Rect(car1.x, car1.y, car1.w, car1.h)
    r2 = pygame.Rect(car2.x, car2.y, car2.w, car2.h)
    return r1.colliderect(r2)

# ========== 游戏初始化变量 ==========
player = PlayerCar()
ai_cars = [AICar() for _ in range(6)]
total_score = 0
game_over = False

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

    # 事件捕获
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        if event.type == pygame.KEYDOWN and game_over:
            if event.key == pygame.K_r:
                # 重置游戏
                player = PlayerCar()
                ai_cars = [AICar() for _ in range(6)]
                total_score = 0
                game_over = False

    if not game_over:
        keys = pygame.key.get_pressed()
        player.update(keys)

        # 更新AI车辆
        for ai in ai_cars:
            ai.update()
            # 玩家和AI相撞扣血扣分
            if rect_collision(player, ai):
                player.get_damage(1.2)
                total_score -= 5

        # 前进获得分数
        if player.vy < -1:
            total_score += abs(player.vy) * 0.015

        # 血量归0游戏结束
        if player.hp <= 0:
            game_over = True

    # 绘制赛道
    pygame.draw.rect(screen, ROAD_GRAY, (road_x_left, 0, ROAD_W, HEIGHT))
    # 道路左右白实线
    pygame.draw.rect(screen, WHITE, (road_x_left - 3, 0, 3, HEIGHT))
    pygame.draw.rect(screen, WHITE, (road_x_right, 0, 3, HEIGHT))
    # 滚动黄色中心线
    for idx in range(len(road_mark_list)):
        road_mark_list[idx] += line_move_speed
        if road_mark_list[idx] > HEIGHT:
            road_mark_list[idx] = -90
        pygame.draw.rect(screen, YELLOW_LINE, (WIDTH//2 - 3, road_mark_list[idx], 6, 45))

    # 绘制AI车
    for ai in ai_cars:
        ai.draw()
    # 绘制玩家车
    player.draw()

    # ===== 右上角UI面板 =====
    panel = pygame.Rect(WIDTH - 180, 10, 170, 130)
    pygame.draw.rect(screen, BLACK_UI, panel, border_radius=8)
    pygame.draw.rect(screen, WHITE, panel, 2, border_radius=8)

    speed_show = abs(player.vy) * 14
    txt_speed = font_info.render(f"车速: {speed_show:.1f} km/h", True, WHITE)
    txt_score = font_info.render(f"分数: {int(total_score)}", True, WHITE)
    txt_hp_text = font_info.render("生命值", True, WHITE)

    # 血条
    hp_bar_bg = pygame.Rect(WIDTH - 170, 82, 140, 14)
    hp_bar_fill = pygame.Rect(WIDTH - 170, 82, player.hp * 1.4, 14)
    pygame.draw.rect(screen, (60,60,60), hp_bar_bg)
    hp_color = GREEN_HP if player.hp > 40 else RED_HP
    pygame.draw.rect(screen, hp_color, hp_bar_fill)

    screen.blit(txt_speed, (WIDTH - 170, 20))
    screen.blit(txt_score, (WIDTH - 170, 48))
    screen.blit(txt_hp_text, (WIDTH - 170, 68))

    # 游戏结束界面
    if game_over:
        over_text = font_big.render("游戏结束 按 R 重新开始", True, (255,30,30))
        screen.blit(over_text, (WIDTH//2 - 160, HEIGHT//2))

    pygame.display.update()