基于Turtle的类Subway Surfers游戏:如何实现障碍物生成速率与移动速度成比例?
基于Turtle的类Subway Surfers游戏:如何实现障碍物生成速率与移动速度成比例?
我明白你遇到的问题了——当游戏速度越来越快时,固定每16次循环生成障碍物会导致屏幕上的障碍物越来越密集,玩家根本反应不过来对吧?其实核心是要让障碍物之间的实际间距保持相对稳定,而不是固定生成的循环次数。
你之前尝试用“16除以速度”的方法,结果变得指数级快,是因为没有找准比例关系:我们需要的不是生成频率和速度成正比,而是生成间隔要和速度成反比,这样才能保证两个障碍物之间的垂直距离大致不变,难度线性提升。
问题根源分析
原代码中,你每16次循环生成一个障碍物,每次循环障碍物移动obstacle_speed距离。初始时,两个障碍物之间的间距是16 * STARTING_MOVE_DISTANCE。但当速度提升后,相同16次循环里,障碍物移动的距离会越来越大,导致新生成的障碍物和前一个的间距被拉得太近,屏幕上的障碍物密度暴增。
解决方案:动态调整生成间隔
我们可以以“初始状态下的障碍物间距”为基准,每次根据当前速度动态计算需要多少个循环来生成下一个障碍物,确保间距始终保持在合理范围。
修改步骤:
- 先确定基准间距:初始时16次循环对应的移动距离,也就是
16 * STARTING_MOVE_DISTANCE - 在游戏循环中,根据当前障碍物速度,计算需要多少个循环才能让障碍物移动完这个基准间距,以此作为新的生成间隔
- 给间隔设置一个最小值(比如2次循环),避免速度过快时间隔过小
修改后的代码示例
main.py 调整部分
import time from turtle import Screen from obstacles import ObstacleManager, STARTING_MOVE_DISTANCE, MOVE_INCREMENT from scoreboard import Scoreboard from player import Player # Create screen screen = Screen() screen.setup(600, 600) screen.tracer(0) # Create objects player = Player() obstacle_manager = ObstacleManager() scoreboard = Scoreboard() # Detect keypress screen.listen() screen.onkeypress(player.move_left, "a") screen.onkeypress(player.move_right, "d") game_is_on = True loops = 0 # 基准间距:初始状态下16次循环障碍物移动的总距离 base_obstacle_spacing = 16 * STARTING_MOVE_DISTANCE # Game loop while game_is_on: time.sleep(0.1) screen.update() loops += 1 # 动态计算生成间隔:基准间距 / 当前速度,保证间距稳定 # 用max()设置最小值,避免速度过快时间隔过小 current_max_loops = max(2, int(base_obstacle_spacing / obstacle_manager.obstacle_speed)) # 当循环次数达到当前间隔时生成障碍物并计分 if loops >= current_max_loops: obstacle_manager.create_obstacle() obstacle_manager.score_up() scoreboard.score_up() loops = 0 obstacle_manager.move_obstacles() # Detect collision with obstacle for obstacle in obstacle_manager.all_obstacles: if obstacle.distance(player) < 10: game_is_on = False scoreboard.game_over() screen.exitonclick()
ObstacleManager 补充完善(确保常量可导入)
from turtle import Turtle import random STARTING_MOVE_DISTANCE = 5 MOVE_INCREMENT = 1 COLORS = ["red", "blue", "green", "yellow", "purple"] OBS_LANE_POSITIONS = [-200, 0, 200] # 对应三车道的x坐标 class ObstacleManager: def __init__(self): self.all_obstacles = [] self.obstacle_speed = STARTING_MOVE_DISTANCE def create_obstacle(self): new_obstacle = Turtle("square") new_obstacle.penup() new_obstacle.color(random.choice(COLORS)) new_obstacle.setheading(270) random_lane_pos = random.choice(OBS_LANE_POSITIONS) new_obstacle.goto(random_lane_pos, 300) # 从屏幕顶部生成障碍物 self.all_obstacles.append(new_obstacle) def move_obstacles(self): for obstacle in self.all_obstacles: obstacle.forward(self.obstacle_speed) def score_up(self): self.obstacle_speed += MOVE_INCREMENT
效果说明
这样修改后,无论障碍物速度怎么提升,两个障碍物之间的垂直间距都会保持和初始状态差不多的水平,难度只会来自于障碍物移动速度的加快,而不是密度的暴增,玩家体验会更平滑。
你也可以根据实际游戏手感调整base_obstacle_spacing的数值,或者调整max()里的最小值,找到最适合的难度曲线。
备注:内容来源于stack exchange,提问作者user29173808




