import pygame
import random
import math
import sys

# 初始化pygame
pygame.init()

# 游戏常量
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
FPS = 60
ROAD_WIDTH = 400
LANE_WIDTH = ROAD_WIDTH // 3
PLAYER_SPEED = 5
OBSTACLE_SPEED_MIN = 3
OBSTACLE_SPEED_MAX = 7
COIN_SPEED = 4
SCORE_INCREMENT = 10
COIN_SCORE = 50

# 颜色定义
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GRAY = (100, 100, 100)
RED = (255, 50, 50)
GREEN = (50, 255, 50)
BLUE = (50, 100, 255)
YELLOW = (255, 255, 0)
ROAD_COLOR = (60, 60, 60)
GRASS_COLOR = (30, 120, 30)
LANE_COLOR = (200, 200, 200)

class PlayerCar:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.width = 40
        self.height = 70
        self.speed = PLAYER_SPEED
        self.color = RED
        self.lane = 1  # 0:左, 1:中, 2:右
        self.score = 0
        self.coins = 0
        self.lives = 3
        
    def draw(self, screen):
        # 绘制赛车主体
        pygame.draw.rect(screen, self.color, (self.x, self.y, self.width, self.height))
        
        # 绘制车窗
        pygame.draw.rect(screen, BLUE, (self.x + 5, self.y + 5, self.width - 10, 15))
        
        # 绘制车灯
        pygame.draw.rect(screen, YELLOW, (self.x + 5, self.y + self.height - 10, 10, 5))
        pygame.draw.rect(screen, YELLOW, (self.x + self.width - 15, self.y + self.height - 10, 10, 5))
        
        # 绘制轮子
        pygame.draw.rect(screen, BLACK, (self.x - 5, self.y + 10, 5, 15))
        pygame.draw.rect(screen, BLACK, (self.x + self.width, self.y + 10, 5, 15))
        pygame.draw.rect(screen, BLACK, (self.x - 5, self.y + self.height - 25, 5, 15))
        pygame.draw.rect(screen, BLACK, (self.x + self.width, self.y + self.height - 25, 5, 15))
    
    def move_left(self):
        if self.lane > 0:
            self.lane -= 1
    
    def move_right(self):
        if self.lane < 2:
            self.lane += 1
    
    def update(self):
        # 根据车道更新位置
        road_left = (SCREEN_WIDTH - ROAD_WIDTH) // 2
        lane_center = road_left + LANE_WIDTH * self.lane + LANE_WIDTH // 2
        self.x = lane_center - self.width // 2
        
        # 确保赛车不会超出道路
        if self.x < road_left:
            self.x = road_left
        if self.x + self.width > road_left + ROAD_WIDTH:
            self.x = road_left + ROAD_WIDTH - self.width
    
    def get_rect(self):
        return pygame.Rect(self.x, self.y, self.width, self.height)

class Obstacle:
    def __init__(self, lane):
        self.lane = lane
        self.width = random.randint(30, 50)
        self.height = random.randint(50, 80)
        road_left = (SCREEN_WIDTH - ROAD_WIDTH) // 2
        lane_center = road_left + LANE_WIDTH * lane + LANE_WIDTH // 2
        self.x = lane_center - self.width // 2
        self.y = -self.height
        self.speed = random.randint(OBSTACLE_SPEED_MIN, OBSTACLE_SPEED_MAX)
        self.color = (random.randint(100, 255), random.randint(100, 255), random.randint(100, 255))
    
    def update(self):
        self.y += self.speed
        return self.y > SCREEN_HEIGHT
    
    def draw(self, screen):
        pygame.draw.rect(screen, self.color, (self.x, self.y, self.width, self.height))
        
        # 绘制车窗
        pygame.draw.rect(screen, BLUE, (self.x + 5, self.y + 5, self.width - 10, 15))
        
        # 绘制轮子
        pygame.draw.rect(screen, BLACK, (self.x - 3, self.y + 10, 6, 10))
        pygame.draw.rect(screen, BLACK, (self.x + self.width - 3, self.y + 10, 6, 10))
        pygame.draw.rect(screen, BLACK, (self.x - 3, self.y + self.height - 20, 6, 10))
        pygame.draw.rect(screen, BLACK, (self.x + self.width - 3, self.y + self.height - 20, 6, 10))
    
    def get_rect(self):
        return pygame.Rect(self.x, self.y, self.width, self.height)

class Coin:
    def __init__(self, lane):
        self.lane = lane
        self.radius = 10
        road_left = (SCREEN_WIDTH - ROAD_WIDTH) // 2
        lane_center = road_left + LANE_WIDTH * lane + LANE_WIDTH // 2
        self.x = lane_center
        self.y = -self.radius
        self.speed = COIN_SPEED
    
    def update(self):
        self.y += self.speed
        return self.y > SCREEN_HEIGHT
    
    def draw(self, screen):
        pygame.draw.circle(screen, YELLOW, (int(self.x), int(self.y)), self.radius)
        pygame.draw.circle(screen, (200, 200, 0), (int(self.x), int(self.y)), self.radius, 2)
        
        # 绘制金币的"$"符号
        font = pygame.font.SysFont(None, 15)
        text = font.render("$", True, BLACK)
        text_rect = text.get_rect(center=(self.x, self.y))
        screen.blit(text, text_rect)
    
    def get_rect(self):
        return pygame.Rect(self.x - self.radius, self.y - self.radius, 
                          self.radius * 2, self.radius * 2)

class Game:
    def __init__(self):
        self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
        pygame.display.set_caption("2D赛车游戏")
        self.clock = pygame.time.Clock()
        self.font = pygame.font.SysFont(None, 36)
        self.small_font = pygame.font.SysFont(None, 24)
        
        # 游戏状态
        self.game_over = False
        self.paused = False
        self.game_started = False
        
        # 游戏对象
        self.player = None
        self.obstacles = []
        self.coins = []
        
        # 计时器
        self.obstacle_timer = 0
        self.coin_timer = 0
        self.score_timer = 0
        
        self.reset_game()
    
    def reset_game(self):
        road_left = (SCREEN_WIDTH - ROAD_WIDTH) // 2
        player_y = SCREEN_HEIGHT - 150
        player_x = road_left + LANE_WIDTH + LANE_WIDTH // 2 - 20
        self.player = PlayerCar(player_x, player_y)
        
        self.obstacles = []
        self.coins = []
        self.obstacle_timer = 0
        self.coin_timer = 0
        self.score_timer = 0
        self.game_over = False
        self.paused = False
    
    def handle_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    pygame.quit()
                    sys.exit()
                
                if not self.game_started:
                    if event.key == pygame.K_SPACE:
                        self.game_started = True
                
                elif self.game_over:
                    if event.key == pygame.K_r:
                        self.reset_game()
                        self.game_started = True
                
                else:
                    if event.key == pygame.K_p:
                        self.paused = not self.paused
                    
                    if event.key == pygame.K_LEFT:
                        self.player.move_left()
                    
                    if event.key == pygame.K_RIGHT:
                        self.player.move_right()
                    
                    if event.key == pygame.K_a:
                        self.player.move_left()
                    
                    if event.key == pygame.K_d:
                        self.player.move_right()
    
    def update(self):
        if not self.game_started or self.game_over or self.paused:
            return
        
        # 更新玩家位置
        self.player.update()
        
        # 增加分数（随时间）
        self.score_timer += 1
        if self.score_timer >= FPS:  # 每秒增加分数
            self.player.score += SCORE_INCREMENT
            self.score_timer = 0
        
        # 生成障碍物
        self.obstacle_timer += 1
        if self.obstacle_timer >= random.randint(30, 90):  # 随机间隔生成障碍物
            lane = random.randint(0, 2)
            self.obstacles.append(Obstacle(lane))
            self.obstacle_timer = 0
        
        # 生成金币
        self.coin_timer += 1
        if self.coin_timer >= random.randint(60, 120):  # 随机间隔生成金币
            lane = random.randint(0, 2)
            self.coins.append(Coin(lane))
            self.coin_timer = 0
        
        # 更新障碍物
        obstacles_to_remove = []
        for i, obstacle in enumerate(self.obstacles):
            if obstacle.update():
                obstacles_to_remove.append(i)
            else:
                # 检测碰撞
                if self.player.get_rect().colliderect(obstacle.get_rect()):
                    self.player.lives -= 1
                    obstacles_to_remove.append(i)
                    
                    if self.player.lives <= 0:
                        self.game_over = True
        
        # 移除屏幕外的障碍物
        for i in reversed(obstacles_to_remove):
            self.obstacles.pop(i)
        
        # 更新金币
        coins_to_remove = []
        for i, coin in enumerate(self.coins):
            if coin.update():
                coins_to_remove.append(i)
            else:
                # 检测收集金币
                if self.player.get_rect().colliderect(coin.get_rect()):
                    self.player.coins += 1
                    self.player.score += COIN_SCORE
                    coins_to_remove.append(i)
        
        # 移除屏幕外的金币
        for i in reversed(coins_to_remove):
            self.coins.pop(i)
    
    def draw_road(self):
        # 绘制草地
        pygame.draw.rect(self.screen, GRASS_COLOR, (0, 0, SCREEN_WIDTH, SCREEN_HEIGHT))
        
        # 绘制道路
        road_left = (SCREEN_WIDTH - ROAD_WIDTH) // 2
        pygame.draw.rect(self.screen, ROAD_COLOR, (road_left, 0, ROAD_WIDTH, SCREEN_HEIGHT))
        
        # 绘制车道线
        for i in range(1, 3):
            lane_x = road_left + LANE_WIDTH * i
            for y in range(0, SCREEN_HEIGHT, 40):
                pygame.draw.rect(self.screen, LANE_COLOR, (lane_x - 2, y, 4, 20))
        
        # 绘制道路边缘
        pygame.draw.rect(self.screen, WHITE, (road_left, 0, 5, SCREEN_HEIGHT))
        pygame.draw.rect(self.screen, WHITE, (road_left + ROAD_WIDTH - 5, 0, 5, SCREEN_HEIGHT))
    
    def draw_hud(self):
        # 绘制分数
        score_text = self.font.render(f"分数: {self.player.score}", True, WHITE)
        self.screen.blit(score_text, (20, 20))
        
        # 绘制金币数量
        coins_text = self.font.render(f"金币: {self.player.coins}", True, YELLOW)
        self.screen.blit(coins_text, (20, 60))
        
        # 绘制生命值
        lives_text = self.font.render(f"生命: {self.player.lives}", True, GREEN)
        self.screen.blit(lives_text, (20, 100))
        
        # 绘制控制说明
        controls = [
            "← → 或 A D: 左右移动",
            "P: 暂停/继续",
            "R: 重新开始(游戏结束时)",
            "ESC: 退出游戏"
        ]
        
        for i, control in enumerate(controls):
            control_text = self.small_font.render(control, True, WHITE)
            self.screen.blit(control_text, (SCREEN_WIDTH - 250, 20 + i * 25))
    
    def draw_start_screen(self):
        overlay = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT), pygame.SRCALPHA)
        overlay.fill((0, 0, 0, 200))
        self.screen.blit(overlay, (0, 0))
        
        title = self.font.render("2D赛车游戏", True, YELLOW)
        title_rect = title.get_rect(center=(SCREEN_WIDTH//2, SCREEN_HEIGHT//2 - 100))
        self.screen.blit(title, title_rect)
        
        start_text = self.font.render("按 SPACE 开始游戏", True, GREEN)
        start_rect = start_text.get_rect(center=(SCREEN_WIDTH//2, SCREEN_HEIGHT//2))
        self.screen.blit(start_text, start_rect)
        
        instructions = [
            "使用方向键或A/D键控制赛车左右移动",
            "避开其他车辆，收集金币",
            "每收集一个金币得50分",
            "每存活一秒得10分",
            "碰撞会减少生命值，生命值为0时游戏结束"
        ]
        
        for i, instruction in enumerate(instructions):
            inst_text = self.small_font.render(instruction, True, WHITE)
            inst_rect = inst_text.get_rect(center=(SCREEN_WIDTH//2, SCREEN_HEIGHT//2 + 60 + i*30))
            self.screen.blit(inst_text, inst_rect)
    
    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))
        
        game_over_text = self.font.render("游戏结束!", True, RED)
        game_over_rect = game_over_text.get_rect(center=(SCREEN_WIDTH//2, SCREEN_HEIGHT//2 - 50))
        self.screen.blit(game_over_text, game_over_rect)
        
        score_text = self.font.render(f"最终分数: {self.player.score}", True, YELLOW)
        score_rect = score_text.get_rect(center=(SCREEN_WIDTH//2, SCREEN_HEIGHT//2))
        self.screen.blit(score_text, score_rect)
        
        coins_text = self.font.render(f"收集金币: {self.player.coins}", True, YELLOW)
        coins_rect = coins_text.get_rect(center=(SCREEN_WIDTH//2, SCREEN_HEIGHT//2 + 40))
        self.screen.blit(coins_text, coins_rect)
        
        restart_text = self.font.render("按 R 重新开始游戏", True, GREEN)
        restart_rect = restart_text.get_rect(center=(SCREEN_WIDTH//2, SCREEN_HEIGHT//2 + 100))
        self.screen.blit(restart_text, restart_rect)
    
    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))
        
        pause_text = self.font.render("游戏暂停", True, YELLOW)
        pause_rect = pause_text.get_rect(center=(SCREEN_WIDTH//2, SCREEN_HEIGHT//2 - 20))
        self.screen.blit(pause_text, pause_rect)
        
        continue_text = self.font.render("按 P 继续游戏", True, GREEN)
        continue_rect = continue_text.get_rect(center=(SCREEN_WIDTH//2, SCREEN_HEIGHT//2 + 20))
        self.screen.blit(continue_text, continue_rect)
    
    def draw(self):
        # 绘制道路
        self.draw_road()
        
        # 绘制游戏对象
        for obstacle in self.obstacles:
            obstacle.draw(self.screen)
        
        for coin in self.coins:
            coin.draw(self.screen)
        
        self.player.draw(self.screen)
        
        # 绘制HUD
        self.draw_hud()
        
        # 绘制游戏状态界面
        if not self.game_started:
            self.draw_start_screen()
        elif self.game_over:
            self.draw_game_over()
        elif self.paused:
            self.draw_pause_screen()
    
    def run(self):
        while True:
            self.handle_events()
            self.update()
            self.draw()
            
            pygame.display.flip()
            self.clock.tick(FPS)

# 运行游戏
if __name__ == "__main__":
    try:
        game = Game()
        game.run()
    except pygame.error as e:
        print(f"游戏运行出错: {e}")
    except Exception as e:
        print(f"发生错误: {e}")
    finally:
        pygame.quit()