2016-10-05 30 views
1

我正在用MonoGame製作基於磁貼的圖形roguelike遊戲,當處理輸入時,播放器移動得太快。使用單獨的按鍵移動播放器不會使應用程序玩起來非常有趣。如何減慢MonoGame

我該如何在遊戲循環之間添加一些時間?當使用Thread.Sleep時,整個程序會卡住,不處理任何輸入。

+0

訣竅是不在遊戲循環迭代之間添加延遲,而是測量循環執行之間的時間並相應地調整時間相關值(例如速度/速度,加速度等)。 – Dai

回答

0

這是我最終決定要做的事情。

我把我的遊戲對象分成組件,一個叫做運動。由於該移動是基於瓦片的,因此我無法使用速度或向量或類似的東西。

代碼簡化了,我沒有包括這裏的所有內容。

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 
} 
0

極其簡單的解決方案是降低MonoGame默認的固定更新速率。這使得你的輸入反應不那麼敏感,並且通常是不希望的。

更好的解決方案是計算自上次更新以來的經過時間,並相應地調整您的移動。這還具有使更多功能變得更加簡單的額外好處,例如爲您的對象增加一些權重,然後可以將其作爲速度的一部分添加,或者可以延長幀速率,而不必緩衝最後一幀並外推中間位置。

1

通常的方法是以「每秒單位」來定義一切的速度。所以玩家會以每秒64像素的速度移動(或者選擇任何速度)。每一幀,MonoGame將調用Update,並傳入一個GameTime實例,並顯示自上一幀以來經過的時間量。你想要做的是將移動速度乘以GameTime.ElapsedGameTime.TotalSeconds。所以如果從上一幀開始秒數的3/4,你會做64 * .75得到48,這是你應該移動你的角色那個幀的像素數量,如果按鈕被按下的話。

如果以「每秒單位數」的方式定義所有內容,無論幀速有多快或多慢,都可以輕鬆保持速度一致。這適用於移動速度(像素/米每秒),轉折率(每秒度數),健康再生(HP每秒)等。MonoGame可以很容易地完成此操作,因爲所有的基本單位類別,如Vector2Vector3,他們的乘法運算符就是爲了這個目的而重載的。