Как создать формат файла сохранения игры в c ++ с использованием STL - PullRequest
0 голосов
/ 23 июля 2011

Я только что узнал о части ввода / вывода STL, более конкретно о fstream. Хотя теперь я могу сохранить двоичную информацию и созданные мной классы на жестком диске, я не уверен, как определить, как информация должна читаться.

Я видел ответ для создания формата файла из этого сообщения:

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

Что я хочу конкретно знать, так это как STL и C ++ ... Поскольку формат предназначен просто для использования в игре, я думаю, что это будет намного проще. Формат должен:

  • Будьте проходимы (я могу просмотреть его, найти начало структуры и, возможно, проверить его имя
  • Уметь хранить несколько классов и данных в одном файле
  • Иметь идентифицируемые начала и окончания разделов: например, пробел в текстовых файлах
  • Может быть, есть собственный значок, чтобы представить его ??

Как мне сделать это в C ++?

1 Ответ

3 голосов
/ 26 июля 2011

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

Одна из лучших вещей, которую вы можете сделать для реализацииформат карты должен иметь анализатор сохранения для каждого класса (некоторые могут быть получены из базового класса «анализатор сохранения»).Так, например, если у вас есть класс проигрывателя, который наследуется от CBaseNPC, вы, скорее всего, можете просто наследовать от CBaseNPC, переопределить анализатор, вызвать функцию базового класса и добавить любые другие необходимые поля, например, если мы имели(псевдокод):

void CBaseNPC::Save() {
     SaveToFile( health );
     SaveToFile( armor );
     SaveToFile( weapons );
     SaveToFile( position );
     SaveToFile( angles );
}

Тогда для вашего класса игрока:

void CPlayer::Save() {
     CBaseNPC::Save();
     SaveToFile( achievement_progress );
}

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

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

Полагаю, лучше всегоЭто можно объяснить на примере, следующий пример может быть простым началом файла сохранения:

Map: {mapname}
Gametime: {gametime}

===Player===
Health: {health}
Armor: {armor}
Weapons: {wep1 (wep1Ammo), wep2 (wep2Ammo), wep3 (wep3Ammo)}
Position: {x, y, z}
Angles: {yaw, pitch, roll} // Could be quaternion instead.
AchievementProgress: {arbritraryData}
===Player===

===NPC-npc_name===
Health: {health}
Armor: {armor}
Weapons: {wep1 (wep1Ammo), wep2 (wep2Ammo), wep3 (wep3Ammo)}
Position: {x, y, z}
Angles: {yaw, pitch, roll} // Could be quaternion instead.
===NPC-npc_name===

===Entity-item_name===
Position: {x, y, z}
Angles: {yaw, pitch, roll}
Model: {modelname}
===Entity-item_name===

Здесь мы использовали строку "===" в качестве разделителя для началапараметры класса и новая строка в качестве разделителя для параметров в каждом классе.

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

Затем он просматривает файл, пока не находит "===", читает строку, с которой встречается, и ищет ее в словаре (возможно, std::map или std::unordered_map), чтобы определить класс длясоздавать (или редактировать) с информацией в файле.Определив тип класса, он может приступить к вызову функции Load() из этого класса, которая будет извлекать всю содержащуюся информацию.Затем анализатор ищет следующий экземпляр "=== {встретившейся строки} ===" и закрывает этот класс.Затем он продолжает следовать той же процедуре со следующим классом.

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

Если у вас все еще есть проблемы или вопросы относительно моего поста, пожалуйста, прокомментируйте, я постараюсь ответить быстро.

...