import pygame
import random
import sys

# 初始化 pygame
pygame.init()

# ============ 游戏配置 ============
SCREEN_WIDTH = 400
SCREEN_HEIGHT = 600
FPS = 60

# 颜色
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GRAY = (100, 100, 100)
DARK_GRAY = (50, 50, 50)
YELLOW = (255, 255, 0)
RED = (220, 50, 50)
GREEN = (50, 200, 50)
BLUE = (50, 100, 220)
ORANGE = (255, 165, 0)
PINK = (255, 150, 200)
PURPLE = (150, 50, 200)

# 创建窗口
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("🏎️ 极速驾驶")
clock = pygame.time.Clock()

# 字体
font_small = pygame.font.Font(None, 28)
font_mid = pygame.font.Font(None, 40)
font_big = pygame.font.Font(None, 60)
font_title = pygame.font.Font(None, 80)


# ============ 玩家车辆类 ============
class PlayerCar:
    def __init__(self):
        self.width = 50
        self.height = 90
        self.x = SCREEN_WIDTH // 2 - self.width // 2
        self.y = SCREEN_HEIGHT - 130
        self.speed = 6
        self.color = RED
        self.acceleration = 0.3
        self.current_speed = 0
        self.max_speed = 8
        self.lives = 3

    def draw(self, surface):
        x, y, w, h = self.x, self.y, self.width, self.height
        # 车身
        pygame.draw.rect(surface, self.color, (x, y, w, h), border_radius=8)
        # 车窗
        pygame.draw.rect(surface, DARK_GRAY, (x + 5, y + 5, w - 10, h // 3), border_radius=4)
        # 车灯
        pygame.draw.rect(surface, YELLOW, (x + 5, y + h - 15, 10, 10), border_radius=3)
        pygame.draw.rect(surface, YELLOW, (x + w - 15, y + h - 15, 10, 10), border_radius=3)
        # 前灯
        pygame.draw.rect(surface, (255, 200, 100), (x + 8, y, 8, 8), border_radius=2)
        pygame.draw.rect(surface, (255, 200, 100), (x + w - 16, y, 8, 8), border_radius=2)

    def move(self, keys):
        if keys[pygame.K_LEFT] or keys[pygame.K_a]:
            self.x -= self.speed
        if keys[pygame.K_RIGHT] or keys[pygame.K_d]:
            self.x += self.speed
        # 边界检测
        if self.x < 60:
            self.x = 60
        if self.x > SCREEN_WIDTH - 60 - self.width:
            self.x = SCREEN_WIDTH - 60 - self.width

    def get_rect(self):
        return pygame.Rect(self.x + 5, self.y + 5, self.width - 10, self.height - 10)


# ============ 敌方车辆类 ============
class EnemyCar:
    def __init__(self):
        self.width = 50
        self.height = 90
        self.x = random.choice([85, 175, 265])
        self.y = -self.height
        self.speed = random.uniform(3, 6)
        self.colors = [BLUE, GREEN, ORANGE, PINK, PURPLE, (0, 180, 180)]
        self.color = random.choice(self.colors)

    def draw(self, surface):
        x, y, w, h = self.x, self.y, self.width, self.height
        # 车身
        pygame.draw.rect(surface, self.color, (x, y, w, h), border_radius=8)
        # 车窗
        pygame.draw.rect(surface, DARK_GRAY, (x + 5, y + h // 2, w - 10, h // 3), border_radius=4)
        # 尾灯
        pygame.draw.rect(surface, RED, (x + 8, y + h - 12, 8, 8), border_radius=2)
        pygame.draw.rect(surface, RED, (x + w - 16, y + h - 12, 8, 8), border_radius=2)

    def update(self):
        self.y += self.speed

    def is_off_screen(self):
        return self.y > SCREEN_HEIGHT

    def get_rect(self):
        return pygame.Rect(self.x + 5, self.y + 5, self.width - 10, self.height - 10)


# ============ 道路类 ============
class Road:
    def __init__(self):
        self.road_x = 60
        self.road_width = SCREEN_WIDTH - 120
        self.line_x = [self.road_x + self.road_width // 3, self.road_x + 2 * self.road_width // 3]
        self.line_y = 0
        self.line_speed = 4

    def draw(self, surface):
        # 道路背景
        pygame.draw.rect(surface, DARK_GRAY, (self.road_x, 0, self.road_width, SCREEN_HEIGHT))
        # 道路边缘线
        pygame.draw.line(surface, YELLOW, (self.road_x, 0), (self.road_x, SCREEN_HEIGHT), 3)
        pygame.draw.line(surface, YELLOW, (self.road_x + self.road_width, 0), (self.road_x + self.road_width, SCREEN_HEIGHT), 3)
        # 中间虚线
        for lx in self.line_x:
            self.line_y %= 80
            for i in range(-1, SCREEN_HEIGHT // 80 + 1):
                y_pos = i * 80 + self.line_y
                if 0 < y_pos < SCREEN_HEIGHT:
                    pygame.draw.rect(surface, WHITE, (lx - 2, y_pos, 4, 40))

    def update(self):
        self.line_y += self.line_speed


# ============ 粒子效果类 ============
class Particle:
    def __init__(self, x, y, color):
        self.x = x
        self.y = y
        self.color = color
        self.vx = random.uniform(-2, 2)
        self.vy = random.uniform(1, 4)
        self.life = random.randint(20, 40)
        self.size = random.randint(2, 5)

    def update(self):
        self.x += self.vx
        self.y += self.vy
        self.life -= 1
        self.size *= 0.98

    def draw(self, surface):
        if self.life > 0:
            alpha = min(255, self.life * 6)
            surf = pygame.Surface((self.size * 2, self.size * 2), pygame.SRCALPHA)
            pygame.draw.circle(surf, (*self.color, alpha), (self.size, self.size), self.size)
            surface.blit(surf, (self.x - self.size, self.y - self.size))


# ============ 游戏主类 ============
class Game:
    def __init__(self):
        self.reset_game()
        self.state = "menu"  # menu, playing, game_over, paused
        self.high_score = 0
        self.difficulty_timer = 0

    def reset_game(self):
        self.player = PlayerCar()
        self.enemies = []
        self.road = Road()
        self.particles = []
        self.score = 0
        self.enemy_spawn_timer = 0
        self.enemy_spawn_delay = 90  # 帧
        self.shake_frames = 0

    def spawn_enemy(self):
        self.enemies.append(EnemyCar())

    def handle_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return False
            if event.type == pygame.KEYDOWN:
                if self.state == "menu":
                    if event.key == pygame.K_SPACE or event.key == pygame.K_RETURN:
                        self.state = "playing"
                        self.reset_game()
                elif self.state == "playing":
                    if event.key == pygame.K_ESCAPE or event.key == pygame.K_p:
                        self.state = "paused"
                elif self.state == "paused":
                    if event.key == pygame.K_ESCAPE or event.key == pygame.K_p or event.key == pygame.K_SPACE:
                        self.state = "playing"
                elif self.state == "game_over":
                    if event.key == pygame.K_SPACE or event.key == pygame.K_RETURN:
                        self.state = "menu"
        return True

    def update(self):
        if self.state != "playing":
            return

        keys = pygame.key.get_pressed()
        self.player.move(keys)
        self.road.update()

        # 生成敌人
        self.enemy_spawn_timer += 1
        if self.enemy_spawn_timer >= self.enemy_spawn_delay:
            self.spawn_enemy()
            self.enemy_spawn_timer = 0

        # 难度递增
        self.difficulty_timer += 1
        if self.difficulty_timer % 300 == 0 and self.enemy_spawn_delay > 30:
            self.enemy_spawn_delay -= 5

        # 更新敌人
        for enemy in self.enemies[:]:
            enemy.update()
            if enemy.is_off_screen():
                self.enemies.remove(enemy)
                self.score += 10

        # 碰撞检测
        player_rect = self.player.get_rect()
        for enemy in self.enemies[:]:
            if player_rect.colliderect(enemy.get_rect()):
                # 产生碰撞粒子
                for _ in range(20):
                    self.particles.append(Particle(
                        enemy.x + enemy.width // 2,
                        enemy.y + enemy.height // 2,
                        enemy.color
                    ))
                self.enemies.remove(enemy)
                self.player.lives -= 1
                self.shake_frames = 15
                if self.player.lives <= 0:
                    self.state = "game_over"
                    if self.score > self.high_score:
                        self.high_score = self.score

        # 更新粒子
        for p in self.particles[:]:
            p.update()
            if p.life <= 0:
                self.particles.remove(p)

        # 尾气粒子
        if self.difficulty_timer % 2 == 0:
            self.particles.append(Particle(
                self.player.x + self.player.width // 2 + random.uniform(-5, 5),
                self.player.y + self.player.height,
                GRAY
            ))

    def draw_menu(self):
        screen.fill((20, 20, 40))

        # 标题
        title_text = font_title.render("极速驾驶", True, YELLOW)
        screen.blit(title_text, (SCREEN_WIDTH // 2 - title_text.get_width() // 2, 120))

        # 装饰线
        pygame.draw.line(screen, YELLOW, (80, 200), (SCREEN_WIDTH - 80, 200), 2)

        # 操作说明
        instructions = [
            "← → 或 A D 键控制方向",
            "躲避其他车辆，坚持越久分越高",
            "",
            "按 SPACE 或 ENTER 开始游戏"
        ]
        for i, text in enumerate(instructions):
            color = WHITE if i < 2 else (150, 150, 150)
            txt = font_small.render(text, True, color)
            screen.blit(txt, (SCREEN_WIDTH // 2 - txt.get_width() // 2, 240 + i * 35))

        # 最高分
        if self.high_score > 0:
            hs_text = font_mid.render(f"最高分: {self.high_score}", True, ORANGE)
            screen.blit(hs_text, (SCREEN_WIDTH // 2 - hs_text.get_width() // 2, 420))

        # 闪烁提示
        if (pygame.time.get_ticks() // 500) % 2 == 0:
            start_text = font_mid.render(">>> 按 SPACE 开始 <<<", True, GREEN)
            screen.blit(start_text, (SCREEN_WIDTH // 2 - start_text.get_width() // 2, 490))

        # 底部装饰
        for i in range(3):
            pygame.draw.rect(screen, [RED, BLUE, GREEN][i],
                           (SCREEN_WIDTH // 2 - 60 + i * 40, 560, 30, 20), border_radius=5)

    def draw_game(self):
        # 背景
        screen.fill((30, 30, 50))

        # 道路
        self.road.draw(screen)

        # 路肩
        for i in range(0, SCREEN_HEIGHT, 40):
            pygame.draw.rect(screen, (80, 80, 80), (0, i, 60, 20))
            pygame.draw.rect(screen, (80, 80, 80), (SCREEN_WIDTH - 60, i, 60, 20))

        # 敌人
        for enemy in self.enemies:
            enemy.draw(screen)

        # 玩家
        self.player.draw(screen)

        # 粒子
        for p in self.particles:
            p.draw(screen)

        # 屏幕震动
        if self.shake_frames > 0:
            offset_x = random.randint(-4, 4)
            offset_y = random.randint(-4, 4)
            screen.blit(screen, (offset_x, offset_y))
            self.shake_frames -= 1

        # UI
        self.draw_ui()

    def draw_ui(self):
        # 分数
        score_text = font_mid.render(f"分数: {self.score}", True, WHITE)
        screen.blit(score_text, (10, 10))

        # 生命值
        lives_text = font_small.render("生命: ", True, WHITE)
        screen.blit(lives_text, (10, 50))
        for i in range(self.player.lives):
            pygame.draw.rect(screen, RED, (80 + i * 25, 55, 20, 15), border_radius=3)

        # 最高分
        hs_text = font_small.render(f"最高: {self.high_score}", True, ORANGE)
        screen.blit(hs_text, (SCREEN_WIDTH - hs_text.get_width() - 10, 10))

    def draw_paused(self):
        self.draw_game()
        # 半透明覆盖
        overlay = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT), pygame.SRCALPHA)
        overlay.fill((0, 0, 0, 150))
        screen.blit(overlay, (0, 0))

        pause_text = font_big.render("暂停", True, WHITE)
        screen.blit(pause_text, (SCREEN_WIDTH // 2 - pause_text.get_width() // 2, 200))
        tip = font_small.render("按 ESC / P / SPACE 继续", True, (200, 200, 200))
        screen.blit(tip, (SCREEN_WIDTH // 2 - tip.get_width() // 2, 280))

    def draw_game_over(self):
        screen.fill((20, 20, 40))

        game_over_text = font_big.render("游戏结束", True, RED)
        screen.blit(game_over_text, (SCREEN_WIDTH // 2 - game_over_text.get_width() // 2, 130))

        score_text = font_mid.render(f"本次得分: {self.score}", True, WHITE)
        screen.blit(score_text, (SCREEN_WIDTH // 2 - score_text.get_width() // 2, 230))

        hs_text = font_mid.render(f"最高分: {self.high_score}", True, ORANGE)
        screen.blit(hs_text, (SCREEN_WIDTH // 2 - hs_text.get_width() // 2, 290))

        if self.score >= self.high_score and self.score > 0:
            new_text = font_small.render("🎉 新纪录！", True, YELLOW)
            screen.blit(new_text, (SCREEN_WIDTH // 2 - new_text.get_width() // 2, 350))

        if (pygame.time.get_ticks() // 500) % 2 == 0:
            restart_text = font_mid.render("按 SPACE 返回主菜单", True, GREEN)
            screen.blit(restart_text, (SCREEN_WIDTH // 2 - restart_text.get_width() // 2, 430))

    def draw(self):
        if self.state == "menu":
            self.draw_menu()
        elif self.state == "playing":
            self.draw_game()
        elif self.state == "paused":
            self.draw_paused()
        elif self.state == "game_over":
            self.draw_game_over()

        pygame.display.flip()

    def run(self):
        running = True
        while running:
            running = self.handle_events()
            self.update()
            self.draw()
            clock.tick(FPS)
        pygame.quit()
        sys.exit()


# ============ 启动游戏 ============
if __name__ == "__main__":
    game = Game()
    game.run()
