如何减慢 MonoGame

How to slow down MonoGame

我正在使用 MonoGame 制作一款基于图块的图形类 roguelike 游戏,在处理输入时玩家移动速度太快。使用单独的单独按键移动播放器并不能使应用程序玩起来非常有趣。

如何在游戏循环之间增加一些时间?使用 Thread.Sleep 时,整个程序会卡住,无法处理任何输入。

最简单的解决方案是降低 MonoGame 默认的固定更新率。这虽然会使您的输入响应速度变慢,但通常是不可取的。

更好的解决方案是计算自上次更新以来经过的时间并相应地调整您的运动。这还有一个额外的好处,可以让更多的功能变得更容易,例如可以将加速度添加为速度的积分,例如为您的对象增加一些重量,或者可以扩展帧速率而无需缓冲最后一帧和推断中间位置.

通常的方法是在"units per second"中定义所有东西的速度。因此玩家将以每秒 64 像素的速度(或您选择的任何速度)移动。每一帧,MonoGame 都会调用 Update,并传入一个 GameTime 实例,其中包含自上一帧以来经过的时间量。您要做的是将移动速率乘以 GameTime.ElapsedGameTime.TotalSeconds。因此,如果自上一帧以来经过了 3/4 秒,您将执行 64 * .75 以获得 48,这是如果按住按钮,您应该在该帧移动角色的像素数。

如果您根据 "Units Per Second" 定义所有内容,则无论帧速率多快或多慢,您都可以轻松保持速度一致。这适用于移动速度(每秒像素/米)、转弯速率(每秒度数)、健康恢复(每秒 hp)等。MonoGame 可以轻松做到这一点,因为所有基本单位 类 ,如 Vector2Vector3,正是为了这个目的而重载了它们的乘法运算符。

这是我最终决定做的事情。

我将我的游戏对象分成组件,其中一个称为运动。由于运动是基于图块的,所以我不能使用速度或矢量或类似的东西。

代码已简化,我没有在此处包含所有内容。

public class Movement 
{
    // define a movement interval and store the elapsed time between moves
    private double interval, elapsedTime;

    public Movement(double interval) 
    {
        this.interval = interval;
    }

    // called when arrow keys are pressed (player)
    public void Move(Direction dir) 
    {
        if(elapsedTime > interval)
        {
            // move
        }
    }

    // called once per frame from the main class Update method
    public void Update(GameTime gameTime)
    {
        if(elapsedTime > interval)
            elapsedTime -= interval;

        // add milliseconds elapsed during the frame to elapsedTime
        elapsedTime += gameTime.ElapsedGameTime.TotalMilliseconds; 
    }
}

public enum Direction 
{
    LEFT,
    RIGHT,
    UP,
    DOWN
}