如何放慢一夫一妻制

本文关键字:一夫一妻制 何放慢 | 更新日期: 2023-09-27 18:11:39

我正在用《MonoGame》制作一款基于贴图的图像roguelike游戏,当处理输入时,玩家移动得太快了。通过单独的按键移动玩家并不会让应用变得有趣。

我该如何在游戏循环之间添加一些时间?当使用Thread.Sleep时,整个程序卡住并且不处理任何输入。

如何放慢一夫一妻制

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

如果你用"单位每秒"来定义一切,你可以很容易地保持速度一致,无论你的帧速率是快是慢。这适用于移动速度(像素/米/秒),旋转速率(每秒度),生命回复(每秒生命值)等。MonoGame很容易做到这一点,因为所有基本的单位类,如Vector2Vector3,都重载了乘法操作符,正是为了这个目的。

最简单的解决方案就是降低你的固定更新率,即MonoGame的默认值。这使得您的输入响应性较差,通常是不受欢迎的。

更好的解决方案是计算自上次更新以来经过的时间,并相应地调整您的移动。这还有一个额外的好处,使更多的功能更容易,例如加速,给你的对象一些重量,然后可以添加为速度的积分,或者你的帧率可以延长,而不必缓冲最后一帧和外推中间位置。

最后我决定这么做。

我把我的游戏对象分成组件,其中一个叫做运动。因为移动是基于贴图的,所以我不能使用速度或矢量或类似的东西。

代码是简化的,我没有包括这里的所有内容。

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
}