import pygame
import random
import sys
from pygame.locals import *

# 初始化pygame
pygame.init()

# 游戏设置
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
FPS = 60
LANE_WIDTH = 150
ROAD_WIDTH = LANE_WIDTH * 3
CAR_SPEED = 8
OBSTACLE_SPEED = 5
SCORE_INCREMENT = 1
COIN_SCORE = 10

# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 120, 255)
YELLOW = (255, 255, 0)
GRAY = (100, 100, 100)
DARK_GRAY = (50, 50, 50)
ROAD_COLOR = (40, 40, 40)
LANE_COLOR = (255, 255, 200)


class PlayerCar:
    def __init__(self):
        self.width = 60
        self.height = 100
        self.x = SCREEN_WIDTH // 2 - self.width // 2
        self.y = SCREEN_HEIGHT - 150
        self.speed = CAR_SPEED
        self.color = BLUE
        self.lane = 1  # 0: 左, 1: 中, 2: 右

    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):
        target_x = (SCREEN_WIDTH - ROAD_WIDTH) // 2 + self.lane * \
            LANE_WIDTH + LANE_WIDTH // 2 - self.width // 2
        # 平滑移动
        self.x += (target_x - self.x) * 0.3

    def draw(self, screen):
        # 绘制车身
        pygame.draw.rect(screen, self.color,
                         (self.x, self.y, self.width, self.height))
        # 绘制车窗
        pygame.draw.rect(screen, (200, 230, 255), (self.x +
                         5, self.y + 5, self.width - 10, 30))
        # 绘制车轮
        pygame.draw.rect(screen, BLACK, (self.x - 5, self.y + 20, 5, 20))
        pygame.draw.rect(
            screen, BLACK, (self.x + self.width, self.y + 20, 5, 20))
        pygame.draw.rect(screen, BLACK, (self.x - 5, self.y + 60, 5, 20))
        pygame.draw.rect(
            screen, BLACK, (self.x + self.width, self.y + 60, 5, 20))


class Obstacle:
    def __init__(self, lane):
        self.width = 60
        self.height = 100
        self.lane = lane
        self.x = (SCREEN_WIDTH - ROAD_WIDTH) // 2 + lane * \
            LANE_WIDTH + LANE_WIDTH // 2 - self.width // 2
        self.y = -self.height
        self.color = random.choice([RED, GREEN, (255, 165, 0)])
        self.speed = OBSTACLE_SPEED + random.random() * 2

    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, DARK_GRAY, (self.x + 5,
                         self.y + 5, self.width - 10, 20))


class Coin:
    def __init__(self, lane):
        self.radius = 15
        self.lane = lane
        self.x = (SCREEN_WIDTH - ROAD_WIDTH) // 2 + \
            lane * LANE_WIDTH + LANE_WIDTH // 2
        self.y = -self.radius
        self.speed = OBSTACLE_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, (255, 200, 0),
                           (int(self.x), int(self.y)), self.radius - 5)
        # 绘制$标志
        font = pygame.font.SysFont(None, 25)
        text = font.render("$", True, BLACK)
        screen.blit(text, (int(self.x) - 5, int(self.y) - 8))


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.SysFont(None, 36)
        self.small_font = pygame.font.SysFont(None, 24)

        self.reset_game()

    def reset_game(self):
        self.player = PlayerCar()
        self.obstacles = []
        self.coins = []
        self.score = 0
        self.game_over = False
        self.level = 1
        self.obstacle_timer = 0
        self.coin_timer = 0

    def handle_events(self):
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()

            if event.type == KEYDOWN:
                if self.game_over:
                    if event.key == K_r:
                        self.reset_game()
                else:
                    if event.key == K_LEFT:
                        self.player.move_left()
                    elif event.key == K_RIGHT:
                        self.player.move_right()

    def spawn_obstacle(self):
        if self.obstacle_timer <= 0:
            lane = random.randint(0, 2)
            self.obstacles.append(Obstacle(lane))
            self.obstacle_timer = random.randint(30, 90)  # 控制障碍物生成频率

    def spawn_coin(self):
        if self.coin_timer <= 0:
            lane = random.randint(0, 2)
            self.coins.append(Coin(lane))
            self.coin_timer = random.randint(60, 150)  # 控制金币生成频率

    def check_collisions(self):
        player_rect = pygame.Rect(self.player.x, self.player.y,
                                  self.player.width, self.player.height)

        # 检查与障碍物的碰撞
        for obstacle in self.obstacles[:]:
            obstacle_rect = pygame.Rect(obstacle.x, obstacle.y,
                                        obstacle.width, obstacle.height)
            if player_rect.colliderect(obstacle_rect):
                self.game_over = True

        # 检查与金币的碰撞
        for coin in self.coins[:]:
            coin_rect = pygame.Rect(coin.x - coin.radius, coin.y - coin.radius,
                                    coin.radius * 2, coin.radius * 2)
            if player_rect.colliderect(coin_rect):
                self.coins.remove(coin)
                self.score += COIN_SCORE

    def update(self):
        if self.game_over:
            return

        self.score += 0.1
        self.level = 1 + int(self.score / 1000)

        # 更新玩家位置
        self.player.update()

        # 更新障碍物
        self.obstacle_timer -= 1
        self.spawn_obstacle()
        for obstacle in self.obstacles[:]:
            if obstacle.update():
                self.obstacles.remove(obstacle)

        # 更新金币
        self.coin_timer -= 1
        self.spawn_coin()
        for coin in self.coins[:]:
            if coin.update():
                self.coins.remove(coin)

        # 检查碰撞
        self.check_collisions()

    def draw_road(self):
        # 绘制道路背景
        road_x = (SCREEN_WIDTH - ROAD_WIDTH) // 2
        pygame.draw.rect(self.screen, ROAD_COLOR,
                         (road_x, 0, ROAD_WIDTH, SCREEN_HEIGHT))

        # 绘制车道线
        for i in range(1, 3):
            lane_x = road_x + i * LANE_WIDTH
            for y in range(0, SCREEN_HEIGHT, 40):
                if y % 80 < 40:  # 虚线效果
                    pygame.draw.rect(self.screen, LANE_COLOR,
                                     (lane_x - 2, y, 4, 20))

        # 绘制道路边缘
        pygame.draw.rect(self.screen, WHITE, (road_x - 5, 0, 5, SCREEN_HEIGHT))
        pygame.draw.rect(self.screen, WHITE, (road_x +
                         ROAD_WIDTH, 0, 5, SCREEN_HEIGHT))

    def draw(self):
        # 绘制天空渐变
        for y in range(SCREEN_HEIGHT):
            color_value = 100 + int(y / SCREEN_HEIGHT * 100)
            pygame.draw.line(self.screen, (color_value, color_value, color_value),
                             (0, y), (SCREEN_WIDTH, y))

        # 绘制道路
        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)

        # 绘制UI
        score_text = self.font.render(f"分数: {int(self.score)}", True, WHITE)
        level_text = self.font.render(f"等级: {self.level}", True, WHITE)
        self.screen.blit(score_text, (20, 20))
        self.screen.blit(level_text, (20, 60))

        # 绘制控制说明
        controls = [
            "← → : 左右移动",
            "R : 重新游戏"
        ]
        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), pygame.SRCALPHA)
            overlay.fill((0, 0, 0, 180))
            self.screen.blit(overlay, (0, 0))

            game_over_text = self.font.render("游戏结束!", True, RED)
            final_score = self.font.render(
                f"最终分数: {int(self.score)}", True, WHITE)
            restart_text = self.font.render("按 R 键重新开始", True, GREEN)

            self.screen.blit(game_over_text,
                             (SCREEN_WIDTH//2 - game_over_text.get_width()//2,
                              SCREEN_HEIGHT//2 - 60))
            self.screen.blit(final_score,
                             (SCREEN_WIDTH//2 - final_score.get_width()//2,
                              SCREEN_HEIGHT//2))
            self.screen.blit(restart_text,
                             (SCREEN_WIDTH//2 - restart_text.get_width()//2,
                              SCREEN_HEIGHT//2 + 60))

        pygame.display.flip()

    def run(self):
        while True:
            self.handle_events()
            self.update()
            self.draw()
            self.clock.tick(FPS)


# 启动游戏
if __name__ == "__main__":
    try:
        game = Game()
        game.run()
    except Exception as e:
        print(f"游戏运行出错: {e}")
        pygame.quit()
