Создание ролевой компьютерной игры 35) Сохранение и восстановление игры
Создание ролевой компьютерной игры
Разработка ролевой игры
35) Сохранение и восстановление игры
Сохранение игры
Перед тем, как продолжить развитие игровых возможностей, реализуем чисто технический, но очень важный режим сохранения текущей игры в файле и последующего ее считывания. Начнем с сохранения, так как пока мы сначала не получим "сэйв"-файл, считать из него данные, очевидно будет невозможно.
Сохранение будем выполнять по нажатии клавиши 's', загрузку - по нажатии клавиши 'l'. Подготовим для этого две пустые процедуры, которые будут располагаться в модуле LowLevel. В принципе, все операторы файлового ввода-вывода Паскаля будут успешно работать на разных платформах - и в Dos, и в Windows, поэтому теоретически данную процедуру мы могли бы считать платформно-независимой. Однако тут будет важен способ выбора имени файла, которое в Windows выполняется с помощью стандартных диалоговых окон, поэтому мы
все же разделим реализации данных процедур.
Модуль Main:
case k of
...
' s ' : SaveGame;
' l ' : LoadGame;
Модуль LowLevel:
{ ----------------- } procedure SaveGame; begin
end;
{ ----------------- } procedure LoadGame; begin
end;
В консольной программе мы не будем создавать собственные специальные редакторы ввода названия файла, так как эта задача не относится к тематике книги. Условимся, что игра всегда будет сохраняться в одни и те же файлы (например, sav.dat) и из него же считываться. В Windows-версии реализовать полноценный режим выбора файла будет гораздо проще.
{ ----------------- } procedure SaveGame; var F: File; begin
Assign(F, ' sav.dat ' );
Rewrite(F,1);
Close(F);
ShowInfo(STR_SAVEOK); end;
Текстовая константа:
STR_SAVEOK = ' Игра успешно сохранена! ' ;
Теперь нам остается точно определить, какие данные и в каком порядке мы хотим сохранить. Игровые типы данных специально готовились таким образом, чтобы объединить все тематические концепции в одной переменной, поэтому процесс сохранения и восстановления не должен вызвать проблемы. Главное - не пропустить никаких важных сведений, для чего полезно просмотреть все интерфейсные разделы всех модулей. Двигаясь по модулям в алфавитном порядке, первую переменную Items мы обнаружим в модуле GameItem. С нее и начнем
процесс сохранения:
for i := 1 to MaxItems do
BlockWrite(F, Items[i], SizeOf(Items[i]));
Далее - массив персонажей и номер текущего героя:
for i := 1 to MaxHeroes do
BlockWrite(F, Heroes[i], SizeOf(Heroes[i]));
BlockWrite(F, CurHero, SizeOf(CurHero));
Схожим образом в файл записывается карта игры и номер уровня:
for i := 1 to MaxMonsters do
BlockWrite(F, Monsters[i], SizeOf(Monsters[i]));
Как видим, объем сохраняемых данных невелик и аккуратен, благо мы хорошо продумали внешние интерфейсы нашей программы!
Создадим сэйв-файл, нажав в некоторый момент времени игры клавишу 's'. Размер его получится 36545 байтов. Возможность сохранения-восстановления важна еще и потому, что по мере усложнения игры отлаживать ее с нуля становится все труднее и дольше.
Процедуру загрузки сохраненной игры оформим так, чтобы порядок ввода данные точно совпадал с порядком их записи в файл. Для этого можно скопировать текст процедуры SaveGame и исправить некоторые операторы:
{ ----------------- } procedure LoadGame; var F: File;
i: Integer; begin
Assign(F, ' sav.dat ' );
Reset(F,1);
for i := 1 to MaxItems do
BlockRead(F, Items[i], SizeOf(Items[i]));
for i := 1 to MaxHeroes do
BlockRead(F, Heroes[i], SizeOf(Heroes[i]));
for i := 1 to MaxMonsters do
BlockRead(F, Monsters[i], SizeOf(Monsters[i]));
Close(F);
ShowInfo(STR_LOADOK); end;
Текстовая константа:
STR_LOADOK = ' Игра успешно загружена! ' ;
С помощью кода такого небольшого объема нам удалось быстро реализовать режим сохраненных игр. Это относится и к многим другим аспектам игры, которые мы достаточно тщательно отрабатывали, особый упор делая на расширение возможностей игры. Читатель может на практике убедиться, что любое из описанных выше игровых направлений доступно для быстрого и объемного расширения. А мы продемонстрируем гибкость созданной архитектуры следующим примером - отыгрыш партией героев.
Исходный код текущей версии для Turbo Pascal (всегда проверен и работоспособен, главный файл - main.pas):