Атрибуты и обработчики как функции
Большинство атрибутов и обработчиков могут быть функциями. Так, например:
disp = function()
p 'яблоко';
endПример не очень удачен, так как проще было бы написать disp = 'яблоко', но показывает синтаксис записи функции.
Основная задача такой функции -- это возврат строки или булевого значения. Сейчас мы рассматриваем возврат строки. Для возврата строки вы можете использовать явную запись в виде:
return "яблоко";При этом ход выполнения кода функции прекращается, и она возвращает движку строку. В данном случае "яблоко".
Более привычным способом вывода являются функции:
- p ("текст") -- вывод текста и пробела;
- pn ("текст") -- вывод текста с переводом строки;
- pr ("текст") -- вывод текста "как есть".
Если ''p''/''pn''/''pr'' вызывается с одним текстовым параметром, то скобки можно опускать.
pn "Нет скобкам!"
Все эти функции дописывают текст в буфер и при возврате из функции возвращают его движку. Таким образом, вы можете постепенно формировать вывод за счёт последовательного выполнения p/pn/pr. Имейте в виду, что автору крайне редко необходимо явно форматировать текст, особенно, если это описание объектов, движок сам расставляет необходимые переводы строк и пробелы для разделения информации разного рода и делает это унифицированным способом.
Вы можете использовать '..' или ',' для склейки строк. Тогда '(' и ')' обязательны. Например:
pn ("Строка 1".." Строка 2");
pn ("Строка 1", "Строка 2");Основное отличие атрибутов от обработчиков событий состоит в том, что обработчики событий могут менять состояние игрового мира, а атрибуты нет. Поэтому, если вы оформляете атрибут (например, 'dsc') в виде функции, помните, что задача атрибута -- это возврат значения, а не изменение состояния игры! Дело в том, что движок обращается к атрибутам в те моменты времени, которые обычно чётко не определены, и не связаны явно с какими-то игровыми процессами!
Важно!
Ещё одной особенностью обработчиков является тот факт, что вы не должны ждать каких-то событий внутри обработчика. То есть, не должно быть каких-то циклов ожидания, или организации задержек (пауз). Дело в том, что задача обработчика -- изменить игровое состояние и отдать управление INSTEAD, который визуализирует эти изменения и снова перейдёт в ожидание действий пользователя. Если вам требуется организовать задержки вывода, вам придётся воспользоваться модулем "timer".
Функции практически всегда содержат условия и работу с переменными. Например:
obj {
nam = 'яблоко';
seen = false;
dsc = function(s)
if not s.seen then
p 'На столе {что-то} лежит.';
else
p 'На столе лежит {яблоко}.';
end
end;
act = function(s)
if s.seen then
p 'Это яблоко!';
else
s.seen = true;
p 'Гм... Это же яблоко!';
end
end;
};Если атрибут или обработчик оформлен как функция, то всегда первый аргумент функции (s) -- сам объект. То-есть, в данном примере, 's' это синоним _'яблоко'. Когда вы работаете с самим объектом в функции, удобнее использовать параметр, а не явное обращение к объекту по имени, так как при переименовании объекта вам не придётся переписывать вашу игру. Да и запись будет короче.
В данном примере при показе сцены в динамической части сцены будет выведен текст: 'На столе что-то лежит'. При взаимодействии с 'что-то', переменная 'seen' объекта 'яблоко' будет установлена в true -- истина, и мы увидим, что это было яблоко.
Как видим, синтаксис оператора 'if' довольно очевиден. Для наглядности, несколько примеров.
if <выражение> then <действия> end
if have 'яблоко' then
p 'У меня есть яблоко!'
end
if <выражение> then <действия> else <действия иначе> end
if have 'яблоко' then
p 'У меня есть яблоко!'
else
p 'У меня нет яблока!'
end
if <выражение> then <действия> elseif <выражение 2> then <действия 2> else <иначе> end -- и т.д.
if have 'яблоко' then
p 'У меня есть яблоко!'
elseif have 'вилка' then
p 'У меня нет яблока, но есть вилка!'
else
p 'У меня нет ни яблока, ни вилки!'
end
Выражение в операторе if может содержать логическое "и" (and), "или" (or), "отрицание" (not) и скобки ( ) для задания приоритетов. Запись вида if <переменная> then означает, что переменная не равна false. Равенство описывается как '==', неравенство '~='.
if not have 'яблоко' and not have 'вилка' then
p 'У меня нет ни яблока, ни вилки!'
end
...
if w ~= apple then
p 'Это не яблоко.';
end
...
if time() == 10 then
p '10 й ход настал!'
endВажно!
В ситуации, когда переменная не была определена, но используется в условии, INSTEAD даст ошибку. Вам придётся заранее определять переменные, которые вы используете.