2016-11-21 2 views
1

Я начинаю свое приключение с помощью игры dev, и я выбрал LibGDX для начала. У меня есть один вопрос о скорости и частоте кадров.Различия в LibGDX в играх с разной частотой кадров

float position x=0f; 
float velosity v=200f; 
float force f=-15f; 
public void update(float deltaTime){ 
    v+=f; 
    v*=deltaTime; 
    x+=v; 
    v*=1/deltaTime; 
} 

В моем коде есть некоторая сила, которая уменьшает скорость с помощью некоторого количества на каждом кадре. Затем после того же времени один игрок, который играет на 30FPS, будет двигаться дальше, чем игрок, играющий на 60FPS, так как сила повлияет на него меньше времени. Я прав? Если да, то как я могу обеспечить, чтобы оба игрока двигались на одинаковом расстоянии? Должен ли я использовать совершенно другой подход?

ответ

1

Вы правильно. Если частота кадров отличается, ваши временные шаги разные, поэтому скорость ускорения будет немного непредсказуемой. Вот почему во многих играх используется фиксированный тайм-код, выполняемый отдельно от частоты кадров игры. Это способ обеспечить, чтобы игра играла то же самое на каждом устройстве.

Если это простая игра, не очень конкурентоспособная, то вам нужно только убедиться, что она остается точной, не обязательно детерминистическим. Если это так, на мой взгляд, вы можете немного обмануть и использовать максимальный временной интервал вместо фиксированного времени. Игра не будет играть точно так же в любое время, но она будет достаточно точной, что никто не заметит. Для этого установите максимальное время дельта. В каждом кадре игры повторно нажимайте обновление до тех пор, пока все время дельта не будет исчерпано, но общее время дельта остается точным. Например:

public static final float MAX_DELTA = 1/50f; 
public static final int MAX_UPDATES_PER_FRAME = 3; 
private float elapsedTime; 

public void render (float deltaTime){ 
    elapsedTime += deltaTime; 
    int updates = 0; 
    while (elapsedTime > 0 && updates < MAX_UPDATES_PER_FRAME){ 
     update(Math.min(MAX_DELTA, elapsedTime)); 
     elapsedTime = Math.max(0, elapsedTime - MAX_DELTA); 
     updates++; 
    } 

    // drawing 
} 

Так что же происходит в то время цикла, вы обновляете физику, пока не догнали текущее время, используя временные шаги по MAX_DELTA или меньше. Вам просто нужно убедиться, что MAX_DELTA достаточно мал, чтобы ваша физика выглядела правильно, и вы не можете проложить тонкие стены. Переменная MAX_UPDATES_PER_FRAME заключается в том, чтобы вы не вводили «спираль смерти», когда есть всплеск центрального процессора, что приводит к слишком большому дельта-времени, и оно начинает падать все дальше и дальше. Вместо этого ваша игра идет немного медленнее, пока не догонит.

Причина, по которой это проще, чем шаг фиксированного времени (famously explained here), заключается в том, что вам не нужно хранить два имитационных интерполяции для рендеринга. При фиксированном временном шаге, приведенный выше код становится:

public static final float FIXED_TIMESTEP = 1/50f; 
public static final int MAX_UPDATES_PER_FRAME = 3; 
private float elapsedTime; 

public void render (float deltaTime){ 
    elapsedTime += deltaTime; 
    int updates = 0; 
    while (elapsedTime >= FIXED_TIMESTEP = && updates < MAX_UPDATES_PER_FRAME){ 
     update(FIXED_TIMESTEP); 
     elapsedTime -= FIXED_TIMESTEP; 
     updates++; 
    } 

    // drawing 
} 

что приводит к уродливым заикания, и может быть исправлено только путем держать две копии всех ваших позиционных данных для игры, чередуя их с каждым кадром, и интерполирования между двумя с левым над elapsedTime, чтобы получить значения, которые подходят для рисования гладкой анимации. Очень сложно!

1

Вы можете умножить движение с дельта-значением времени (время между кадрами), чтобы сделать его независимым от частоты кадров. Использование libgdx вы можете использовать следующий метод:

Gdx.graphics.getDeltaTime(); 

Вот простой пример:

x += 500 * Gdx.graphics.getDeltaTime(); 
+0

Это то, что я делаю в своем вопросе, я умножаю скорость с дельта-временем и добавляю ее в текущее положение. Но когда скорость не постоянна и уменьшается в каждом кадре, игрок с более низким fps будет двигаться дальше, чем игрок с высоким fps, не так ли? – androlama

+0

Да, он движется дальше на каждом кадре, но игрок с более высоким fps двигается больше, чем игрок с более низким fps.Таким образом, каждый перемещает более или менее то же расстояние – Fefux

+0

Согласно моим расчетам через 1 секунду Игрок с 1fps будет идти примерно на 40 единиц дальше, чем игрок с 30 кадрами в секунду, если они оба одновременно нажимают кнопку «вперед». 40 - довольно большая разница, и я не хочу, чтобы пользователи воспользовались этим и получили более высокие баллы с более низким fps – androlama