import pygame
import random
import sys
import traceback

def main():
    try:
        pygame.init()
        SCREEN_WIDTH = 600
        SCREEN_HEIGHT = 800
        screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
        pygame.display.set_caption("2D 赛车 - 高速公路躲避")

        BLACK = (0, 0, 0)
        WHITE = (255, 255, 255)
        GRAY = (50, 50, 50)
        RED = (200, 0, 0)
        YELLOW = (200, 200, 0)
        PURPLE = (128, 0, 128)
        ORANGE = (255, 165, 0)

        PLAYER_WIDTH = 50
        PLAYER_HEIGHT = 80
        ENEMY_WIDTH = 50
        ENEMY_HEIGHT = 80

        PLAYER_SPEED = 8
        ENEMY_BASE_SPEED = 5
        SPEED_INCREMENT = 0.5
        MAX_ENEMY_SPEED = 15
        SPAWN_DELAY_MIN = 45
        SPAWN_DELAY_MAX = 70

        player_x = SCREEN_WIDTH // 2 - PLAYER_WIDTH // 2
        player_y = SCREEN_HEIGHT - PLAYER_HEIGHT - 20
        player_rect = pygame.Rect(player_x, player_y, PLAYER_WIDTH, PLAYER_HEIGHT)

        enemies = []
        score = 0
        highscore = 0
        enemy_speed = ENEMY_BASE_SPEED
        game_active = True
        spawn_counter = 0
        spawn_wait = random.randint(SPAWN_DELAY_MIN, SPAWN_DELAY_MAX)
        road_offset = 0

        font = pygame.font.SysFont("Arial", 36)
        small_font = pygame.font.SysFont("Arial", 24)

        def draw_car(x, y, width, height, color):
            pygame.draw.rect(screen, color, (x, y, width, height))
            wheel_radius = 8
            wheel_y_offset = 10
            pygame.draw.circle(screen, BLACK, (x + 10, y + height - wheel_y_offset), wheel_radius)
            pygame.draw.circle(screen, BLACK, (x + width - 10, y + height - wheel_y_offset), wheel_radius)
            pygame.draw.circle(screen, BLACK, (x + 10, y + wheel_y_offset), wheel_radius)
            pygame.draw.circle(screen, BLACK, (x + width - 10, y + wheel_y_offset), wheel_radius)
            pygame.draw.rect(screen, YELLOW, (x + 5, y + height - 15, 10, 8))
            pygame.draw.rect(screen, YELLOW, (x + width - 15, y + height - 15, 10, 8))

        def draw_road(offset):
            # 路面背景
            screen.fill(GRAY)
            # 左右路肩线
            pygame.draw.line(screen, WHITE, (50, 0), (50, SCREEN_HEIGHT), 5)
            pygame.draw.line(screen, WHITE, (SCREEN_WIDTH - 50, 0), (SCREEN_WIDTH - 50, SCREEN_HEIGHT), 5)
            # 中间虚线（滚动）
            dash_length = 30
            dash_gap = 30
            dash_width = 10
            # 修正：将浮点数 offset 计算结果强制转为整数，避免 range() 报错
            start_y = int(offset % (dash_length + dash_gap) - (dash_length + dash_gap))
            for y in range(start_y, SCREEN_HEIGHT, dash_length + dash_gap):
                pygame.draw.rect(screen, WHITE, (SCREEN_WIDTH//2 - dash_width//2, y, dash_width, dash_length))

        def reset_game():
            nonlocal player_x, player_rect, enemies, score, enemy_speed, game_active
            nonlocal spawn_counter, spawn_wait, road_offset, highscore
            player_x = SCREEN_WIDTH // 2 - PLAYER_WIDTH // 2
            player_rect.x = player_x
            enemies.clear()
            score = 0
            enemy_speed = ENEMY_BASE_SPEED
            game_active = True
            spawn_counter = 0
            spawn_wait = random.randint(SPAWN_DELAY_MIN, SPAWN_DELAY_MAX)
            road_offset = 0

        def spawn_enemy():
            enemy_x = random.randint(50, SCREEN_WIDTH - ENEMY_WIDTH - 50)
            enemies.append(pygame.Rect(enemy_x, -ENEMY_HEIGHT, ENEMY_WIDTH, ENEMY_HEIGHT))

        clock = pygame.time.Clock()
        running = True

        while running:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running = False
                if event.type == pygame.KEYDOWN and event.key == pygame.K_r and not game_active:
                    reset_game()

            if game_active:
                # 玩家移动
                keys = pygame.key.get_pressed()
                if keys[pygame.K_LEFT] and player_x > 50:
                    player_x -= PLAYER_SPEED
                if keys[pygame.K_RIGHT] and player_x < SCREEN_WIDTH - PLAYER_WIDTH - 50:
                    player_x += PLAYER_SPEED
                player_rect.x = player_x

                # 动态难度
                calculated_speed = ENEMY_BASE_SPEED + (score // 100) * SPEED_INCREMENT
                enemy_speed = min(calculated_speed, MAX_ENEMY_SPEED)

                # 生成敌人
                spawn_counter += 1
                if spawn_counter >= spawn_wait:
                    spawn_enemy()
                    spawn_counter = 0
                    spawn_wait = random.randint(SPAWN_DELAY_MIN, SPAWN_DELAY_MAX)

                # 移动敌人，加分，移除出界
                for enemy in enemies[:]:
                    enemy.y += enemy_speed
                    if enemy.top > SCREEN_HEIGHT:
                        enemies.remove(enemy)
                        score += 10
                        if score > highscore:
                            highscore = score

                # 碰撞检测
                for enemy in enemies:
                    if player_rect.colliderect(enemy):
                        game_active = False
                        break

                # 道路滚动偏移量
                road_offset = (road_offset + enemy_speed * 0.5) % 60

            # 绘制所有元素
            draw_road(road_offset)
            for enemy in enemies:
                color = PURPLE if (score // 50) % 2 == 0 else ORANGE
                draw_car(enemy.x, enemy.y, ENEMY_WIDTH, ENEMY_HEIGHT, color)
            draw_car(player_x, player_y, PLAYER_WIDTH, PLAYER_HEIGHT, RED)

            # 显示分数、速度、最高分
            score_img = font.render(f"Score: {score}", True, WHITE)
            screen.blit(score_img, (10, 10))
            speed_img = small_font.render(f"Speed: {enemy_speed:.1f}", True, WHITE)
            screen.blit(speed_img, (10, 50))
            high_img = small_font.render(f"Best: {highscore}", True, WHITE)
            screen.blit(high_img, (10, 80))

            # 游戏结束界面
            if not game_active:
                overlay = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT), pygame.SRCALPHA)
                overlay.fill((0, 0, 0, 180))
                screen.blit(overlay, (0, 0))
                go_text = font.render("GAME OVER", True, RED)
                rst_text = small_font.render("Press R to Restart", True, WHITE)
                fin_text = font.render(f"Score: {score}", True, WHITE)
                screen.blit(go_text, (SCREEN_WIDTH//2 - go_text.get_width()//2, SCREEN_HEIGHT//2 - 60))
                screen.blit(fin_text, (SCREEN_WIDTH//2 - fin_text.get_width()//2, SCREEN_HEIGHT//2))
                screen.blit(rst_text, (SCREEN_WIDTH//2 - rst_text.get_width()//2, SCREEN_HEIGHT//2 + 50))

            pygame.display.flip()
            clock.tick(60)

        pygame.quit()
        sys.exit()

    except Exception as e:
        with open("racing_error.log", "w") as f:
            traceback.print_exc(file=f)
        print("程序崩溃，错误信息已保存到 racing_error.log")
        input("按回车键退出...")

if __name__ == "__main__":
    main()