Перейти к основному содержимому

Назад: Переходы внутри локации

Служебные локации

В QSP существует возможность привязать вызов некоторых локаций к определённым событиям. Например, к выделению предмета в окне предметов, или к переходу на новую локацию с помощью операторов GOTO/XGOTO.

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

! назначили обработчик выделения предмета:
$onobjsel = 'ONOBJSEL'
! назначили обработчик перехода на новую локацию:
$onnewloc = 'перерисовка'
! сняли обработчик добавления предмета:
$onobjadd = ''

Примечание: При использовании операторов "KILLALL, KILLVAR" очищаются также все системные переменные. В том числе и переменные, через которые назначаются локации-обработчики.

Когда событие происходит, указанная локация вызывается точно так же, как если бы мы вызывали её с помощью оператора GOSUB, с тем исключением, что на всех служебных локациях восстанавливаются глобальные переменные. Пример:

# start
$ongsave = 'ogs'
i = 99

act 'Save Game':
local i = 17
! на экран будет выведено значение 99
savegame '1.sav'
end

act 'Print i':
local i = 137
! на экран будет выведено 137
gosub 'ogs'
end
-

# ogs
*pl i
-

В этом примере при сохранении игры на экран будет выведено число 99 из глобальной переменной i. Если же локация ogs вызывается не как служебная, на неё транслируются значения локальной переменной i, объявленной в действии.

События в QSP

В этом разделе перечислены все события в QSP, к которым можно привязать автоматический вызов локаций.

Загрузка состояния игры

$ONGLOAD — содержит название локации-обработчика события "загрузка состояния игры" (далее "обработчик загрузки состояния"). Иными словами, в эту переменную записывается название локации, код которой будет выполняться всякий раз после того, как был загружен файл состояния игры ("файл сохранения") с помощью команды OPENGAME. Название локации может быть любым.

Назначаем в качестве обработчика загрузки состояния локацию "on_game_load":

$ongload="on_game_load"

Теперь сразу после выполнения команды OPENGAME плеер будет автоматически вызывать локацию "on_game_load".

Чтобы отключить обработчик загрузки состояния, нужно задать переменной $ONGLOAD пустое значение:

$ongload=""

Сохранение состояния игры

$ONGSAVE - содержит название локации-обработчика события "сохранение состояния игры" (далее "обработчик сохранения состояния"). Иными словами, в эту переменную записывается название локации, код которой будет выполняться всякий раз перед тем, как записать состояние игры в новый, или уже существующий, файл состояния игры ("файл сохранения") с помощью команды SAVEGAME. Название локации может быть любым.

Назначаем в качестве обработчика сохранения состояния локацию "on_game_save":

$ongsave="on_game_save"

Теперь сразу после выполнения команды SAVEGAME плеер будет автоматически вызывать локацию "on_game_save".

Чтобы отключить обработчик сохранения состояния, нужно задать переменной $ONGSAVE пустое значение:

$ongsave=""

Добавление предмета в окно предметов

$ONOBJADD — содержит название локации-обработчика события "добавление предмета в окно предметов" (далее "обработчик добавления предмета"). Иными словами, в эту переменную записывается название локации, код которой выполняется всякий раз после добавления предмета в окно предметов с помощью команды ADDOBJ. Название локации может быть любым.

При добавлении предмета этой локации-обработчику передаются два аргумента, значения которых можно получить из $ARGS[0] и $ARGS[1] соответственно:

  • $ARGS[0] - название добавленного предмета
  • $ARGS[1] - путь к картинке добавленного предмета

Данная локация полезна, к примеру, для ограничения вместительности рюкзака.

Назначаем в качестве обработчика добавления предмета локацию "on_object_add":

$onobjadd="on_object_add"

Теперь сразу после выполнения команды ADDOBJ плеер будет автоматически вызывать локацию "on_object_add".

Чтобы отключить обработчик добавления предмета, нужно задать переменной $ONOBJADD пустое значение:

$onobjadd=""

Удаление предмета из окна предметов

$ONOBJDEL — содержит название локации-обработчика события "удаление предмета" (далее "обработчик удаления предмета"). Иными словами, в эту переменную записывается название локации, код которой выполняется всякий раз после удаления предмета с помощью команды DELOBJ. Если воспользоваться командой KILLOBJ, то это будет аналогично серии команд DELOBJ, соответственно и локация-обработчик будет вызвана столько раз, сколько предметов будет удалено с помощью KILLOBJ. Название локации может быть любым.

При использовании команды KILLALL локация-обработчик удаления предмета не вызывается, поскольку системная переменная $ONOBJDEL уничтожается раньше удаления предметов.

При удалении предмета обработчику удаления предмета передаётся аргумент, значение которого можно получить из $ARGS[0]:

  • $ARGS[0] - название удалённого предмета

Назначаем в качестве обработчика удаления предмета локацию "on_object_del":

$onobjdel="on_object_del"

Теперь сразу после выполнения команды DELOBJ плеер будет автоматически вызывать локацию "on_object_del". А сразу после выполнения команды KILLOBJ локация "on_object_del" будет вызвана столько раз, сколько предметов удалено этой командой.

Данная локация полезна, к примеру, для проверки возможности удаления предмета:

! например есть предмет, который нам пригодится по сюжету
if $args[0]="Важный артефакт":
! восстанавливаем предмет
addobj $args[0]
end

Чтобы отключить обработчик удаления предмета, нужно задать переменной $ONOBJDEL пустое значение:

$onobjdel=""

Выделение предмета в окне предметов

$ONOBJSEL — содержит название локации-обработчика события "выделение предмета" (далее "обработчик выделения предмета"). Иными словами, в этой переменной указывается название локации, код на которой выполняется всякий раз при выделении предмета. Выделение предмета происходит непосредственно при "нажатии" на предмет (щелчок мышью по предмету). Название локации может быть любым.

Назначаем в качестве обработчика выделения предмета локацию "on_object_select":

$onobjsel="on_object_select"

Теперь всякий раз после щелчка мышью на предмете будет выполняться код локации "on_object_select".

Данная локация полезна, к примеру, для вывода информации о предмете, или для вызова меню предмета. Получить название выбранного предмета можно через функцию $SELOBJ.

if $selobj = 'чайник':
p 'Cамый обычный чугунный чайник.'
end

При выборе играющим какого-либо предмета, он остаётся выделенным. Повторно выделить уже выделенный предмет нельзя. Снять выделение можно командой UNSELECT.

if $selobj = 'нож':
*p 'Этим ножом даже хлеба не нарежешь.'
end
unselect &! или UNSEL

Переход на новую локацию

$ONNEWLOC — содержит название локации-обработчика перехода на новую локацию (далее "обработчик перехода"). Иными словами, в эту переменную записывается название локации, код которой выполняется каждый раз после выполнения кода локации, на которую был осуществлён переход с помощью операторов GOTO или XGOTO. Управление игрой передаётся игроку уже после выполнения кода на этой локации-обработчике. Название локации может быть любым.

Назначаем в качестве обработчика перехода локацию "on_goto_newloc":

$onnewloc="on_goto_newloc"

Теперь всякий раз после выполнения кода локации, на которую был осуществлён переход с помощью операторов GOTO или XGOTO, будет автоматически вызываться локация "on_goto_newloc".

Получить название локации, на которую был осуществлён переход, можно с помощью функции $CURLOC.

if $curloc = 'дом': кошка = 1

Чтобы отключить обработчик перехода, нужно задать переменной $ONNEWLOC пустое значение:

$onnewloc=""

Выделение действия

$ONACTSEL — содержит название локации-обработчика события "выделение действия" (обработчик выделения действий). Иными словами, в этой переменной указывается название локации, код на которой срабатывает, когда одно из выведенных на экран действий выделяется. Название локации может быть любым.

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

Действие нельзя выделить повторно, если оно уже выделено.

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

Назначаем в качестве обработчика выделения действий локацию "on_mouse":

$onactsel="on_mouse"

Теперь всякий раз при наведении указателя мыши на любое из действий в окне действий, будет вызываться локация "on_mouse".

Данная локация полезна, к примеру, для вывода изображений или проигрывания звуков при выборе действий. Получить название выбранного действия можно через функцию $SELACT.

if instr(1,$selact,'пойти'): play 'sounds\walk.mp3'

Чтобы отключить обработчик выделения действий, нужно задать переменной $ONACTSEL пустое значение:

$onactsel=""

Ввод в строке ввода

$USERCOM — содержит название локации-обработчика строки ввода (поля ввода) (далее "обработчик ввода"). Код данной локации-обработчика выполняется, если курсор установлен в строку ввода в момент нажатия клавиши "Enter". Название локации может быть любым.

Назначаем в качестве локации-обработчика строки ввода локацию "user_command_line":

$usercom="user_command_line"

Теперь, если игрок установит курсор в строку ввода и начнёт нажимать клавишу "Enter", всякий раз при нажатии клавиши "Enter" будет вызываться локация "user_comand_line".

Полезна при организации парсера (управление игрой с помощью строки ввода), или для организации отладчика. Получить текст, введённый игроком в поле ввода, можно с помощью функции $USER_TEXT.

Пример кода для локации-обработчика:

! если введённый текст соответствует названию существующей локации
if (loc $user_text)=-1:
! осуществляем переход на эту локацию
goto $user_text
elseif instr($user_text,'>')=1:
! если первый символ в строке ввода это ">" ,
! выполняем введённый в строку текст, как код
dynamic $mid($user_text,2)
end

Чтобы отключить обработчик ввода, нужно задать переменной $USERCOM пустое значение:

$usercom=""

Так же см. статью "Ввод текста игроком".

Локация-счётчик

Локация-счётчик не является обработчиком какого-то события, как такового. Она вызывается через примерно равные промежутки времени, поэтому здесь мы выделяем её в отдельную группу. Тем не менее, всё, что справедливо для локаций-обработчиков событий, справедливо и для локации-счётчика.

$COUNTER — содержит название локации-счётчика. Локация-счётчик может использоваться для реалтаймовых событий (то есть событий, происходящих в действительном времени); например, плавное изменение цвета фона, постепенный вывод текста на экран, плейлист для постоянного проигрывания музыки и другие. Название локации может быть любым.

Как правило, чтобы не путаться, локацию называют так же, как и служебную переменную — "Counter":

$counter='Counter'

Чтобы отключить выполнение локации-счётчика, нужно задать пустое значение переменной $COUNTER:

$counter=""

SETTIMER

Локация-счетчик вызывается через одинаковые промежутки времени, по умолчанию каждые 500 мс, т.е. 2 раза в секунду. Автоматическое обновление интерфейса срабатывает с той же частотой. Промежутки задаются оператором SETTIMER в миллисекундах.

Внимание!!! Период, выставляемый через SETTIMER — это очень условная величина. Он показывает только примерное время, когда локация-счётчик будет добавлена на выполнение в очередь. Непосредственно выполниться локация-счётчик может чуть позже, а то и сильно позже. Будьте бдительны.

Если ваша локация-счётчик называется "on_time", на самой первой локации в игре нужно написать:

$counter='on_time'

Теперь, если вы не использовали оператор SETTIMER, примерно каждые 500 миллисекунд будет вызываться локация "on_time".

Примеры выставления таймера:

SETTIMER 1000/частота_в_герцах
SETTIMER 1000*период_в_секундах

Так же см. статью "Реальное время".

Несколько обработчиков на одно событие

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

Эта задача решается двумя способами.

  • Назначаем в качестве локации-обработчика какого-либо события одну локацию, а уже из неё с помощью GOSUB вызываем необходимые локации, на которых мы разместили фрагменты кода:

    ! самая первая локация в игре
    $counter='counter'
    ! локация counter
    gosub 'playlist'
    gosub 'rabbit_hole','animation'
  • Используем системную переменную, в которую обычно прописываем название локации-обработчика, как массив, и прописываем локации, на которых мы разместили фрагменты кода, в ячейки этого массива:

    $counter[0]='playlist'
    $counter[1]='rabbit_hole'

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

Обратите внимание на преимущества и недостатки каждого способа.

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

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

Вперёд: Динамический код