2016-10-05 8 views
1

Я делаю графическую игру с мозаикой на основе плитки с MonoGame, а при обработке ввода игрок слишком быстро перемещается. Перемещение проигрывателя с отдельными нажатиями отдельных клавиш не делает приложение ужасно забавным для игры.Как замедлить 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, то есть количество пикселей, которое должно перемещать ваш персонаж в этот кадр, если кнопка удерживается нажатой.

Если вы определяете все в терминах «Единицы в секунду», вы можете легко поддерживать скорость, независимо от того, насколько быстро или медленнее ваша частота кадров. Это работает для скорости движения (пикселы/метры в секунду), скорости вращения (в градусах в секунду), регенерации здоровья (л.с. в секунду) и т. Д. MonoGame упрощает это, потому что все основные классы блоков, такие как Vector2 и Vector3, имеют свои операторы умножения, перегруженные именно для этой цели.