Как Вы разделяете игровую логику от дисплея?

Trace.WriteLine должен работать, если вы выберете правильный вывод (раскрывающийся список с надписью «Показать вывод из», найденным в окне «Выход»)

19
задан Chris 24 August 2008 в 15:39
поделиться

8 ответов

Koen Болтает, имеет очень подробная статья о различных игровых установках цикла.

Он покрывает:

  • фут в секунду, зависящий от Постоянной Игровой Скорости
  • Игровая Скорость, зависящая от Переменного кадр/с
  • Постоянная Игровая Скорость с Максимальным кадр/с
  • Постоянная Игровая Скорость, независимая от Переменного кадр/с

(Это заголовки, которые вытягивают от статьи, в порядке желательности.)

8
ответ дан 30 November 2019 в 03:12
поделиться

Вы могли заставить свой игровой цикл быть похожим:

int lastTime = GetCurrentTime();
while(1) {
    // how long is it since we last updated?
    int currentTime = GetCurrentTime();
    int dt = currentTime - lastTime;
    lastTime = currentTime;

    // now do the game logic
    Update(dt);

    // and you can render
    Draw();
}

Затем просто необходимо записать Ваш Update() функция для принятия во внимание дифференциала времени; например, если Вы имеете объект, перемещающийся на некоторой скорости v, затем обновляете ее положение v * dt каждый кадр.

4
ответ дан 30 November 2019 в 03:12
поделиться

Я думаю, что вопрос показывает немного неверного толкования того, как должны быть разработаны игровые механизмы. Который совершенно в порядке, потому что они - чертовски сложные вещи, в которых трудно разобраться ;)

у Вас создается корректное впечатление, что Вы хотите то, что является Независимостью Уровня вызванного кадра. Но это не только относится к Рендерингу Кадров.

Кадр А в единственных потоковых игровых механизмах обычно упоминается как Галочка. Каждая Галочка Вы обрабатываете вход, обрабатываете игровую логику и представляете кадр, базирующийся прочь результатов обработки.

то, Что Вы хотите сделать, смочь обработать Вашу игровую логику на уровне любого кадр/с (Кадры в секунду) и иметь детерминированный результат.

Это становится проблемой в следующем случае:

Проверка ввела: - вход является ключевым: 'W', что означает, что мы перемещаем персонажа вперед 10 единиц:

playerPosition + = 10;

Теперь, так как Вы делаете этот каждый кадр, если Вы достигаете 30 кадр/с, Вы переместите 300 единиц в секунду.

, Но если Вы вместо этого достигаете 10 кадр/с, Вы только переместите 100 единиц в секунду. И таким образом Ваша игровая логика не Независимая Частота кадров.

Счастливо, чтобы решить эту проблему и заставить Вашу игру играть логическую Независимую Частоту кадров довольно простая задача.

Первый, Вам нужен таймер, который будет считать время, которое каждый кадр занимает для рендеринга. Это число с точки зрения секунд (так 0,001 секунды для завершения Галочки) затем умножается на то, чем когда-либо случается так, что Вы хотите быть Независимой Частотой кадров. Так в этом случае:

При содержании 'W'

playerPosition + = 10 * frameTimeDelta;

(Delta является необычным словом для "Изменения В Чем-то")

, Таким образом, Ваш плеер переместит некоторую часть 10 в единственной Галочке, и после целой секунды Галочек, Вы переместите полные 10 единиц.

Однако это будет падать когда дело доходит до свойств, где уровень изменения также изменяется со временем, например, ускоряющийся механизм. Это может быть разрешено при помощи более усовершенствованного интегратора, такого как "Verlet".

Многопоточный Подход

, Если Вы все еще интересуетесь ответом на свой вопрос (так как я не ответил на это, но представил альтернативу), здесь это. Разделение Игровой Логики и Рендеринг в различных потоках. Это имеет, это - спины ничьей все же. Достаточно так, чтобы подавляющее большинство Игровых Механизмов остается одиноким поточное.

Но это вовсе не значит существует только когда-либо один поток, работающий в так называемых единственных потоковых механизмах. Но все значительные задачи обычно находятся в одном центральном потоке. Некоторые вещи как Обнаружение коллизий могут быть многопоточными, но обычно фаза Коллизии Галочки, которую блоки до всех потоков возвратили, и механизм, вернулась к единственному потоку выполнения.

Многопоточность представляет целый, очень большой класс проблем, даже некоторые производительности начиная со всего, даже контейнеры, должны быть ориентированы на многопотоковое исполнение. И Игровые Механизмы являются очень сложными программами для начала, таким образом, это редко стоит добавленной сложности многопоточности их.

Фиксированный Подход Временного интервала

Наконец, как другой комментатор отметил, имея временной интервал Фиксированного размера, и управляя, как часто Вы "ступаете", игровая логика может также быть очень эффективным способом обработать это со многими преимуществами.

Связанный здесь для полноты, но другого комментатора также связывается с ним: Фиксируют Ваш Временной интервал

30
ответ дан 30 November 2019 в 03:12
поделиться

Была превосходная статья о flipcode об этом назад в день. Я хотел бы вскопать его и представить его для Вас.

http://www.flipcode.com/archives/Main_Loop_with_Fixed_Time_Steps.shtml

Это, приятно продумал цикл для выполнения игры:

  1. Единственный потоковый
  2. В фиксированных игровых часах
  3. С графикой максимально быстро с помощью интерполированных часов

ну, по крайней мере это - то, что я думаю, что это.:-) Слишком плохо обсуждение, которое преследовало после этой регистрации, более трудно найти. Возможно, Wayback Machine может помочь там.

time0 = getTickCount();
do
{
  time1 = getTickCount();
  frameTime = 0;
  int numLoops = 0;

  while ((time1 - time0)  TICK_TIME && numLoops < MAX_LOOPS)
  {
    GameTickRun();
    time0 += TICK_TIME;
    frameTime += TICK_TIME;
    numLoops++;
// Could this be a good idea? We're not doing it, anyway.
//    time1 = getTickCount();
  }
  IndependentTickRun(frameTime);

  // If playing solo and game logic takes way too long, discard pending
time.
  if (!bNetworkGame && (time1 - time0)  TICK_TIME)
    time0 = time1 - TICK_TIME;

  if (canRender)
  {
    // Account for numLoops overflow causing percent  1.
    float percentWithinTick = Min(1.f, float(time1 - time0)/TICK_TIME);
    GameDrawWithInterpolation(percentWithinTick);
  }
}
while (!bGameDone);
2
ответ дан 30 November 2019 в 03:12
поделиться

Enginuity имеет немного отличающийся, но интересный подход: Пул Задачи.

0
ответ дан 30 November 2019 в 03:12
поделиться

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

, Но необходимо синхронизировать право потоков путь ;) Будет требоваться много времени для реализации, поэтому если игра не будет слишком большой, однопоточное решение будет прекрасно.

кроме того, извлекая GUI в отдельный поток, кажется, большой подход. Вы когда-либо видели, "Что миссия завершает" всплывающее сообщение, в то время как единицы перемещаются в стратегиях в реальном времени? Это - то, что я говорю о :)

0
ответ дан 30 November 2019 в 03:12
поделиться

На основе моего опыта (не очень) Jesse и ответы Adam должны поместить Вас на правильном пути.

, Если Вы после дополнительной информации и понимания, как это работает, я нашел, что примеры приложения для TrueVision, 3D , были очень полезны.

-2
ответ дан 30 November 2019 в 03:12
поделиться

Это не относится к более высоким программным абстракциям, т.е. к государственным машинам и т.д.

Можно управлять движением и ускорением, настраивая те, что с вашим временным интервалом. Но как насчет таких вещей, как запуск звука через 2,55 секунды после того или иного момента, или изменение уровень игры 18,25 сек. спустя и т.д.

, которые могут быть привязаны к аккумулятору (счетчику) истекшего времени, но эти тайминги могут испортится, если ваша частота смены кадров упадет ниже разрешения сценария. т.е. если ваша высшая логика требует 0,05 сек. гранулярности и вы падаете ниже 20 кадров в секунду.

Детерминизм может быть сохранен, если игровая логика запущена на отдельном "потоке". (на программном уровне, который я предпочел бы для этого, или на уровне ОС) с фиксированной временной линией, независимой от fps.

Наказание может заключаться в том, что вы можете тратить время процессора в промежутках между кадрами, если происходит немногое, но, думаю, оно того стоит.

0
ответ дан 30 November 2019 в 03:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: