Я пишу свой финал для курса «Программирование видеоигр» и хочу знать, как создать файл сохранения для моей игры, чтобы пользователь мог играть, а затем вернуться позже. Любая идея, как это сделать, все, что я делал раньше, было программами с одним запуском.
c++
savegame
serialization
Такер Морган
источник
источник
Ответы:
Вам нужно использовать сериализацию, чтобы сохранить переменные в памяти на жестком диске. Существует много типов сериализации, в .NET XML является распространенным форматом, хотя доступны двоичные и JSON-сериализаторы. Я не большой программист на C ++, но быстрый поиск показал пример сериализации в C ++:
Существуют библиотеки, которые предлагают функции сериализации. Некоторые упоминаются в других ответах.
Переменные, которые вас заинтересуют, вероятно, будут связаны с состоянием игры. Например, вы, вероятно, хотите знать этот тип информации
Вам действительно все равно, какие текстуры используются (если ваш игрок не может изменить их внешний вид, это особый случай), потому что они обычно одинаковы. Вы должны сосредоточиться на сохранении важных данных игрового состояния.
Когда вы запускаете игру, вы начинаете как обычно для «новой» игры (при этом загружаются ваши текстуры, модели и т. Д.), Но в соответствующее время вы загружаете значения из файла сохранения обратно в объект состояния игры, заменяя новый «по умолчанию» новым состояние игры. Затем вы позволяете игроку возобновить игру.
Я очень упростил это здесь, но вы должны получить общее представление. Если у вас есть более конкретный вопрос, задайте новый вопрос здесь, и мы можем попытаться помочь вам в этом.
источник
Обычно это зависит от вашей игры. Я уверен, что вы уже узнали о записи и чтении из файлов в ваших классах. Основная идея:
То, что вы пишете, зависит от вас, это зависит от вашей игры. Один из способов записи - вывести нужные переменные в определенном порядке в виде потока байтов. Затем при загрузке прочитайте их в вашей программе в том же порядке.
Например (в быстром псевдокоде):
источник
Вероятно, существует множество способов сделать это, но самый простой, который я всегда находил и использовал как лично, так и профессионально, - это создать структуру, содержащую все значения, которые я хочу сохранить.
Затем я просто записываю / копирую данные в файл и из файла, используя базовые значения файлового ввода-вывода. InventoryCount - это число структур Item, которые сохраняются после основной структуры SaveGameData в файле, поэтому я знаю, сколько из них нужно прочитать после извлечения этих данных. Ключевым моментом здесь является то, что когда я хочу сохранить что-то новое, кроме списка элементов или чего-либо подобного, все, что мне когда-либо нужно, это добавить значение в структуру some where. Если это список элементов, тогда мне нужно будет добавить проход чтения, как я уже подразумевал, для объектов Item, счетчик в главном заголовке и затем записи.
Это имеет обратную сторону - делает разные версии файла сохранения несовместимыми друг с другом без специальной обработки (даже если это просто значения по умолчанию для каждой записи в основной структуре). Но в целом это позволяет легко расширять систему, просто добавляя новое значение данных и добавляя в него значение при необходимости.
Опять же, есть несколько способов сделать это, и это может привести к C, а не к C ++, но это уже сделано!
источник
Сначала вам нужно решить, какие данные нужно сохранить. Например, это может быть местоположение персонажа, его счет и количество монет. Конечно, ваша игра, вероятно, будет намного сложнее, поэтому вам нужно будет сохранить дополнительные данные, такие как номер уровня и список врагов.
Затем, напишите код, чтобы сохранить это в файл (использование ofstream). Относительно простой формат, который вы можете использовать, выглядит следующим образом:
И так файл будет выглядеть так:
Что означало бы, что он был на позиции (14, 96) со счетом 4200 и 100 монет.
Вам также нужно написать код для загрузки этого файла (используйте ifstream).
Спасение врагов может быть сделано путем включения их позиции в файл. Мы можем использовать этот формат:
Сначала
number_of_enemies
читается, а затем каждая позиция читается с помощью простого цикла.источник
Одно добавление / предложение может добавить уровень шифрования к вашей сериализации, чтобы пользователи не могли редактировать свои значения в тексте как "9999999999999999999". Хорошая причина сделать это - предотвратить целочисленные переполнения (например).
источник
Я думаю, что ваша лучшая ставка - это boost :: serialization, потому что ее легко распространить в вашей иерархии. Вам нужно только вызвать функцию сохранения / загрузки верхнего объекта, и все ваши классы легко создаются.
См. Http://www.boost.org/doc/libs/1_49_0/libs/serialization/doc/index.html.
источник
Для полноты картины я хочу упомянуть библиотеку сериализации c ++, которую я лично использую и еще не упоминал: cereal .
Он прост в использовании и имеет приятный, чистый синтаксис для сериализации. Он также предлагает несколько типов форматов, которые вы можете сохранить (XML, Json, Binary (включая переносную версию с сохранением порядка байтов)). Он поддерживает наследование и только для заголовков,
источник
Ваша игра скомпрометирует структуры данных (надеюсь?), Которые вам нужно преобразовать в байты (сериализовать), чтобы вы могли хранить их. В будущем вы можете загрузить эти байты обратно и преобразовать их обратно в исходную структуру (десериализация). В C ++ это не так сложно, потому что рефлексия очень ограничена. Но все же, некоторые библиотеки могут помочь вам здесь. Я написал статью об этом: https://rubentorresbonet.wordpress.com/2014/08/25/an-overview-of-data-serialization-techniques-in-c/ По сути, я бы предложил вам взглянуть на библиотека зерновых, если вы можете использовать компиляторы C ++ 11. Не нужно создавать промежуточные файлы, как с protobuf, так что вы сэкономите там время, если хотите быстрых результатов. Вы также можете выбрать между двоичным и JSON, так что это может помочь при отладке.
Кроме того, если безопасность является проблемой, вы можете зашифровать / расшифровать данные, которые вы храните, особенно если вы используете удобочитаемые форматы, такие как JSON. Здесь полезны такие алгоритмы, как AES.
источник
Вы должны использовать
fstream
для файлов ввода / вывода. Синтаксис простой EX:Или
В вашем файле возможны другие действия: добавление , двоичный файл , усечение и т. Д. Вы должны использовать тот же синтаксис, что и выше, вместо этого мы помещаем std :: ios: :( flags), например:
ios::out
для выходной операцииios::in
для операции вводаios::binary
для бинарной (необработанной) операции ввода-вывода вместо символьнойios::app
для начала писать в конце файлаios::trunc
если файл уже существует, замените старый контент и замените его новымios::ate
- установить указатель файла «в конце» для ввода / выводаПример:
Вот более полный, но простой пример.
источник
goto
s вы будете линчевать в общественных местах. Не используйтеgoto
с.