Создание игры на C ++ с использованием параллельной обработки

StackOverflow https://stackoverflow.com/questions/73117

Вопрос

Я хотел "эмулировать" популярную флеш-игру Chrontron на C ++, и мне нужна была некоторая помощь для начала.(ПРИМЕЧАНИЕ:Не для разрядки, просто тренируюсь для себя)

Basics:
Player has a time machine. On each iteration of using the time machine, a parallel state
is created, co-existing with a previous state. One of the states must complete all the
objectives of the level before ending the stage. In addition, all the stages must be able
to end the stage normally, without causing a state paradox (wherein they should have
been able to finish the stage normally but, due to the interactions of another state,
were not).

Итак, это в некотором роде объясняет, как работает игра.Вам стоит немного поиграть в нее, чтобы действительно понять, в чем моя проблема.

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

АКТУАЛЬНЫЙ ВОПРОС:

Теперь, когда у меня есть некоторые приблизительные спецификации, мне нужна помощь в принятии решения о том, какие структуры данных использовать для этого и почему.Кроме того, я хочу знать, какой графический API / уровень я должен использовать для этого:SDL, OpenGL или DirectX (мой текущий выбор - SDL).И как бы я приступил к реализации параллельных состояний?С параллельными потоками?

РЕДАКТИРОВАТЬ (Для большей ясности):
ОПЕРАЦИОННАЯ система - Windows (поскольку это хобби-проект, возможно, позже это будет сделано в Linux)
Графика - 2D Язык - C ++ (должен быть C ++ - это практика для курса в следующем семестре)

Вопрос-Без ответа:SDL :OpenGL :Прямой X
Q-Ответил:Избегайте Параллельной обработки
Q-Ответил:Используйте STL для реализации пошаговых действий.

So far from what people have said, I should:
1. Use STL to store actions.
2. Iterate through actions based on time-step.
3. Forget parallel processing -- period. (But I'd still like some pointers as to how it
could be used and in what cases it should be used, since this is for practice).

Добавляя к вопросу, я бы сказал, что раньше я в основном использовал C #, PHP и Java, поэтому я бы не назвал себя опытным программистом.Какие специфические знания в области C ++ помогли бы мне упростить этот проект?(то есть.Векторы?)

Это было полезно?

Решение

Что вам следует сделать, так это сначала прочитать и понять игровой цикл с "фиксированным временным шагом" (вот хорошее объяснение: http://www.gaffer.org/game-physics/fix-your-timestep).

Затем то, что вы делаете, это сохраняете список пар счетчика кадров и действия.Пример STL:

std::list<std::list<std::pair<unsigned long, Action> > > state;

Или, может быть, вектор списков пар.Чтобы создать состояние, для каждого действия (взаимодействия с игроком) вы сохраняете номер кадра и то, какое действие выполнено, скорее всего, вы получили бы наилучшие результаты, если бы действие было просто "клавиша <X> нажата" или "клавиша <X> отпущена".:

state.back().push_back(std::make_pair(currentFrame, VK_LEFT | KEY_PRESSED));

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

typedef std::list<std::pair<unsigned long, Action> > StateList;
std::list<StateList::iterator> stateIteratorList;
//
foreach(it in stateIteratorList)
{
  if(it->first == currentFrame)
  {
    performAction(it->second);
    ++it;
  }
}

Я надеюсь, вы уловили эту идею...

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

Когда дело доходит до graphics API, я бы выбрал SDL, поскольку это, вероятно, самое простое, с чего вы можете начать.Вы всегда можете использовать OpenGL из SDL позже, если захотите перейти на 3D.

Другие советы

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

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

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

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

Лично я бы просто вел список действий, а затем для каждой последующей итерации начинал чередовать их вместе.Например, если список представлен в формате <[итерация.действие]> затем в третий раз будут выполняться действия 1.1, 2.1, 3.1, 1.2, 2.2, 3.3, и т.д.

После краткого ознакомления с описанием, я думаю, у вас есть правильная идея, у меня был бы объект state, который содержит данные о состоянии, и поместил бы это в связанный список...Я не думаю, что вам нужны параллельные потоки...

что касается графического API, я использовал только opengl и могу сказать, что он довольно мощный и имеет хороший C / C ++ API, opengl также был бы более кроссплатформенным, поскольку вы можете использовать библиотеку messa на компьютерах с * Nix.

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

Этот вопрос немного двусмысленный.Я вижу, что вы собираетесь написать это на C ++, но для какой операционной системы вы это кодируете?Собираетесь ли вы сделать его кроссплатформенным и какую графику вы бы хотели, т.е. 3D, 2D, high end, веб-версию?

Так что, по сути, нам нужно гораздо больше информации.

Параллельная обработка - это не выход.Вы должны просто "записать" действия игроков, а затем воспроизвести их для "предыдущих действий".

Таким образом, вы создаете вектор (односвязный список) векторов, который содержит действия.Просто сохраните номер кадра, в котором было выполнено действие (или дельту), и завершите это действие с "фиктивным ботом", который представляет игрока в этом конкретном случае.Вы просто перебираете состояния и запускаете их одно за другим.

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

Если вы не отчаялись использовать C ++ для собственного образования, вам обязательно следует обратить внимание на XNA для вашего игрового и графического фреймворка (он использует C #).Это абсолютно бесплатно, оно многое делает за вас, и вскоре вы сможете продавать свою игру на Xbox Live.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top