Онлайн-справочник по самым часто задаваемым вопросам из темы "Как сделать?" на форуме QSP.su

17.3. Как сделать чекпойнты в игре?

В: Как сделать чекпойнты в игре?

Как сделать так, чтобы игру можно было начинать с последнего сохранения?

О:

Прежде всего "последнее" сохранение мы всегда будем записывать в файл "autosave.sav". Делается это просто. Там, где нужно сохраниться пишем такую команду:

savegame "autosave.sav"

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

act "Продолжить игру":
    opengame "autosave.sav"
end

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

Что ж, нам нужна некая переменная, которая будет означать наличие сохранения. Назовём эту переменную `savetrue` и обернём действие в условие:

if savetrue=1:
    act "Продолжить игру":
        opengame "autosave.sav"
    end
end

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

Ввести ещё один файл сохранения, назовём его "system.sav". Таким образом в момент сохранения игры мы будем писать два файла:

! выставляем значение переменной-маркера на единицу
savetrue=1
! сохраняем игру в системный файл сохранения
savegame "system.sav"
! выставляем значение переменной-маркера на ноль
savetrue=0
! сохраняем состояние чекпоинта
savegame "autosave.sav"

Таким образом в момент сохранения игры мы создаём два файла сохранения: системный и непосредственно файл для продолжения игры с чекпоинта. Лучше оформить этот код на отдельной локации, назвать её например "checkpoint", а затем в нужном месте просто вызывать, используя `gosub`:

gosub "checkpoint"

Теперь мы можем загрузить сохранение "system.sav" и при этом получим значение переменной-маркера, равное единице, но так же при этом игрок окажется на той локации, где это сохранение было сделано, а нам нужно вернуть его к стартовой локации. Как сделать это?

Нужно завести локацию-обработчик события "загрузка состояния игры". Создаём новую локацию и называем её, например, "при_загрузке". Далее указываем плееру, какую именно локацию ему нужно использовать, как локацию-обработчик загрузки состояния игры. Для этого в системную переменную `$ongload` вносим название нашей вновь созданной локации (пишем на самой первой локации в игре):

$ongload="при_загрузке"

На локации "при_загрузке" пишем такой код:

! если значение переменной-маркера равно единице
if savetrue=1:
    
! выставляем ещё одну переменную маркер
    lock_resave=1
    
! возвращаемся на стартовую локацию
    goto "начало"
end

А код на локации "начало" (самой первой локации в игре, стартовой локации) правим так:

! если значение переменной проверки сохранения равно 1
if savetrue=1:
    
! сохранение есть, выводим действие
    act "Продолжить игру":
        opengame "autosave.sav"
    end
elseif lock_resave=0:
! иначе если проверка сохранения не заблокирована
    
! пытаемся открыть системное сохранение
    opengame "system.sav"
end

Итак, что будет происходить при этом. Когда игрок первый раз запустит игру, обе переменные-маркеры будут равны нулю. Плеер попытается загрузить состояние "system.sav", но поскольку этот файл ещё не создан, плеер просто проигнорирует команду:

opengame "system.sav"

По мере прохождения, игрок будет посещать "контрольные точки", где игра будет сохранять состояние автоматически, используя написанную нами процедуру "checkpoint". При этом перед сохранением состояния в условно-системный файл "system.sav" переменной-маркеру `savetrue` будет присваиваться значение `1`, а перед сохранением состояния, которое мы будем использовать для загрузки "контрольной точки" ("autosave.sav"), этой переменной будет присваиваться значение `0`.

Теперь, если игрок повторно откроет игру, обе переменные-маркеры будут равны нулю. Плеер попытается загрузить состояние "system.sav", и поскольку оно теперь создано, загрузит его. Переменной-маркеру `savetrue` будет присвоено значение `1`, так как это значение ей было присвоено перед сохранением "system.sav". Далее произойдёт автоматическое посещение локации-обработчика "при_загрузке".

На этой локации произойдёт проверка условия, правда ли переменной `savetrue` присвоена единица, и это окажется правдой. Переменной-маркеру `lock_resave` будет так же присвоена единица и команда `goto` отправит игрока на стартовую локацию.

Теперь сработает условие, проверяющее, правда ли переменной `savetrue` присвоена единица, и игрок увидит на экране действие "Продолжить игру".

А когда игрок выберет это действие, произойдёт загрузка состояния "autosave.sav", но поскольку в этом состоянии переменной-маркеру `savetrue` присвоен ноль, при обращении к локации "при_загрузке" условие не сработает и перезаход на стартовую локацию повторно не произойдёт.

Используя условно-системный файл сохранения, Вы можете не только организовать систему чекпоинтов, но и упростить для игрока различные вступительные части игры и кат-сцены при повторном входе, восстанавливать различные параметры игры частично, а не полностью, и т.д.