You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

基于Turtle的类Subway Surfers游戏:如何实现障碍物生成速率与移动速度成比例?

基于Turtle的类Subway Surfers游戏:如何实现障碍物生成速率与移动速度成比例?

我明白你遇到的问题了——当游戏速度越来越快时,固定每16次循环生成障碍物会导致屏幕上的障碍物越来越密集,玩家根本反应不过来对吧?其实核心是要让障碍物之间的实际间距保持相对稳定,而不是固定生成的循环次数。

你之前尝试用“16除以速度”的方法,结果变得指数级快,是因为没有找准比例关系:我们需要的不是生成频率和速度成正比,而是生成间隔要和速度成反比,这样才能保证两个障碍物之间的垂直距离大致不变,难度线性提升。

问题根源分析

原代码中,你每16次循环生成一个障碍物,每次循环障碍物移动obstacle_speed距离。初始时,两个障碍物之间的间距是16 * STARTING_MOVE_DISTANCE。但当速度提升后,相同16次循环里,障碍物移动的距离会越来越大,导致新生成的障碍物和前一个的间距被拉得太近,屏幕上的障碍物密度暴增。

解决方案:动态调整生成间隔

我们可以以“初始状态下的障碍物间距”为基准,每次根据当前速度动态计算需要多少个循环来生成下一个障碍物,确保间距始终保持在合理范围。

修改步骤:

  1. 先确定基准间距:初始时16次循环对应的移动距离,也就是16 * STARTING_MOVE_DISTANCE
  2. 在游戏循环中,根据当前障碍物速度,计算需要多少个循环才能让障碍物移动完这个基准间距,以此作为新的生成间隔
  3. 给间隔设置一个最小值(比如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

火山引擎 最新活动