Как зайти в Даркнет?!
25th January, 01:11
6
0
Как в tkinter из поля ввода Entry получить значение в одну переменную и обновить строку кнопкой, затем получить ещё одно введённое значение и затем сложить их. Ниже пример кода
21st July, 19:00
894
0
Программа, которая создает фейковые сервера в поиске игровых серверов CS 1.6 Steam
21st March, 17:43
948
0
Очень долго работает Update запрос Oracle
27th January, 09:58
914
0
не могу запустить сервер на tomcat HTTP Status 404 – Not Found
21st January, 18:02
905
0
Где можно найти фрилансера для выполнения поступающих задач, на постоянной основе?
2nd December, 09:48
938
0
Разработка мобильной кроссплатформенной военной игры
16th July, 17:57
1724
0
период по дням
25th October, 10:44
3955
0
Пишу скрипты для BAS только на запросах
16th September, 02:42
3720
0
Некорректный скрипт для закрытия блока
14th April, 18:33
4613
0
прокидывать exception в блоках try-catch JAVA
11th March, 21:11
4381
0
Помогите пожалуйста решить задачи
24th November, 23:53
6086
0
Не понимаю почему не открывается детальное описание продукта
11th November, 11:51
4350
0
Нужно решить задачу по программированию на массивы
27th October, 18:01
4396
0
Метода Крамера С++
23rd October, 11:55
4309
0
помогите решить задачу на C++
22nd October, 17:31
4002
0
Помогите решить задачу на python с codeforces
22nd October, 11:11
4492
0
Python с нуля: полное руководство для начинающих
18th June, 13:58
2599
0
Как вы отделяете логику игры от дисплея?
Как можно сделать так, чтобы количество кадров дисплея в секунду не зависело от логики игры? Таким образом, логика игры работает с одинаковой скоростью независимо от того, насколько быстро видеокарта может визуализировать.
Я думаю, что этот вопрос показывает некоторое непонимание того, как должны быть разработаны игровые движки. Что совершенно нормально, потому что это чертовски сложные вещи, которые трудно исправить ;)
У вас сложилось правильное впечатление, что вы хотите того, что называется независимостью частоты кадров. Но это относится не только к кадрам рендеринга.
Фрейм в однопоточных игровых движках обычно называют тиком. Каждый тик вы обрабатываете входные данные, обрабатываете логику игры и визуализируете кадр, основанный на результатах обработки.
Все, что вы хотите сделать, - это иметь возможность обрабатывать свою логику игры в любое время FPS (кадров в секунду) и иметь детерминированный результат.
Это становится проблемой в следующем случае:
Регистрация вход: - Ввод является ключевым: 'W', что означает, что мы перемещаем персонажа игрока вперед на 10 единиц:
playerPosition += 10;
Теперь, поскольку вы делаете это каждый кадр, если вы работаете со скоростью 30 FPS, вы будете двигаться со скоростью 300 единиц в секунду.
Но если вы вместо этого работаете на 10 FPS, вы будете двигаться только 100 единиц в секунду. И поэтому ваша игровая логика не зависит от частоты кадров.
К счастью, решить эту проблему и сделать вашу игру независимой от частоты кадров логики-довольно простая задача.
Во-первых, вам нужен таймер, который будет считать время, необходимое для визуализации каждого кадра. Это число в секундах (так что 0.001 секунд для завершения Тика) затем умножается на то, что вы хотите быть независимым от частоты кадров. Так что в данном случае:
При проведении 'W'
playerPosition += 10 * frameTimeDelta;
(Дельта-это модное слово для "изменения в чем-то")
Таким образом, ваш игрок переместит некоторую часть 10 за один тик, и после полной секунды тиков вы переместите все 10 единиц.
Однако это будет падать, когда речь заходит о свойствах, где скорость изменения также меняется с течением времени, например, ускоряющийся автомобиль. Это можно решить с помощью более продвинутого интегратора, такого как "Verlet".
Многопоточный Подход
Если вы все еще заинтересованы в ответе на свой вопрос (поскольку я не ответил на него, но представил альтернативу), вот он. Разделение игровой логики и рендеринга на разные потоки. Однако у него есть свои недостатки. Достаточно того, что подавляющее большинство игровых движков остаются однопоточными.
Это не значит, что существует только один поток, работающий в так называемых однопоточных движках. Но все важные задачи обычно находятся в одном центральном потоке. Некоторые вещи, такие как обнаружение столкновений, могут быть многопоточными, но обычно фаза столкновения Тика блокируется до тех пор, пока все потоки не вернутся, и механизм не вернется к одному потоку выполнения.
Многопоточность представляет собой целый, очень большой класс проблем, даже некоторые проблемы производительности, так как все, даже контейнеры, должны быть потокобезопасными. А игровые движки-это прежде всего очень сложные программы, так что вряд ли стоит дополнительно усложнять их многопоточность.
Фиксированный Временной Шаг Подхода
Наконец, как отметил другой комментатор, имея фиксированный размер временного шага и контролируя, как часто вы "step" логика игры также может быть очень эффективным способом обработки этого со многими преимуществами.
Ссылка здесь для полноты картины, но другой комментатор также ссылается на нее: Исправьте Свой Временной Шаг
У Коэна Виттерса есть очень подробная статья о различных настройках цикла игры.
Он покрывает:
- FPS зависит от постоянной скорости игры
- Скорость игры зависит от переменной FPS
- Постоянная скорость игры с максимумом FPS
- Постоянная скорость игры, не зависящая от переменной FPS
(Это заголовки, взятые из статьи, в порядке желательности.)
Вы могли бы сделать свой игровой цикл похожим:
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 каждый кадр.
В свое время об этом была отличная статья на flipcode. Я хотел бы откопать его и подарить вам.
http://www.flipcode.com/archives/Main_Loop_with_Fixed_Time_Steps.shtml
Это хорошо продуманная петля для запуска игры:
- Однопоточный
- На фиксированных игровых часах
- С графикой как можно быстрее с помощью интерполированных часов
Ну, по крайней мере, я так думаю. :- ) Жаль, что обсуждение, которое последовало после этой публикации, найти труднее. Возможно, машина обратного пути может помочь там.
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.55 секунд после того или иного, или изменение уровень игры 18.25 секунд спустя и т.д.
Который может быть привязан к накопителю времени истекшего кадра (счетчику), BUT эти тайминги могут получить облажались, если частота кадров падает ниже вашего разрешения сценария состояния то есть, если ваша высшая логика нуждается в детализации 0.05 сек, и вы падаете ниже 20fps.
Детерминизм может быть сохранен, если логика игры выполняется на отдельном "thread" (на программном уровне, который я бы предпочел для этого, или на уровне OS) с фиксированным временным срезом, независимым от fps.
Наказание может заключаться в том, что вы можете потратить cpu времени между кадрами, если ничего не происходит, но я думаю, что оно того стоит.
Однопоточные решения с временными задержками перед отображением графики хороши, но я думаю, что прогрессивный способ заключается в запуске игровой логики в одном потоке и отображении в другом потоке.
Но вы должны правильно синхронизировать потоки;) это займет много времени для реализации, так что если ваша игра не слишком большая, однопоточное решение будет прекрасным.
Кроме того, извлечение GUI в отдельный поток кажется отличным подходом. Вы когда-нибудь видели всплывающее сообщение "Mission complete", когда юниты перемещаются в играх RTS? Вот о чем я говорю :)
По моему опыту (не очень) ответы Джесси и Adam должны направить вас на правильный путь.
Если вам нужна дополнительная информация и понимание того, как это работает, я обнаружил, что примеры приложений для TrueVision 3D были очень полезны.