fix in pict scaling in original theme

This commit is contained in:
p.kosyh 2011-07-30 11:54:58 +00:00
parent e5e1d65632
commit fac7a14456
3 changed files with 251 additions and 210 deletions

1
debian/changelog vendored
View file

@ -3,6 +3,7 @@ instead (1.4.5) unstable; urgency=low
* bug fix in rnd() w/o parameter;
* bug fix in for_each;
* bug fix in txtnb and \;
* bug fix in original theme picture scaling;
* callpush/callpop/cctx/strip do_ini and some others moved to stead;
* win.align added to theme;
* theme_name added;

View file

@ -1,18 +1,22 @@
====== Базовая документация ======
===== Общие сведения =====
Код игр для STEAD пишется на lua (5.1), поэтому, знание этого языка полезно, хотя и не необходимо. Код движка на lua занимает около ~3000 строк и лучшей документацией является изучение его кода.
Код игр для STEAD пишется на //lua (5.1)//, поэтому, знание этого языка полезно, хотя и не необходимо. Код движка на lua занимает около ~3000 строк и лучшей документацией является изучение его кода.
Главное окно игры содержит информацию о статической и динамической части сцены, активные события и картинку сцены с возможными переходами в другие сцены (в графическом интерпретаторе).
//Главное окно// игры содержит информацию о статической и динамической части сцены, активные события и картинку сцены с возможными переходами в другие сцены (в графическом интерпретаторе).
Динамическая часть сцены составлена из описаний объектов сцены, она отображается всегда.
//Статическая часть сцены// отображается только один раз, при показе сцены, или при повторении команды ''look'' (в графическом интерпретаторе -- клик на названии сцены).
//
Статическая часть сцены отображается только один раз, при показе сцены, или при повторении команды look (в графическом интерпретаторе -- клик на названии сцены).
Динамическая часть сцены// составлена из описаний объектов сцены, она отображается всегда.
Игроку доступны объекты доступные на любой сцене -- инвентарь. Игрок может взаимодействовать с объектами инвентаря и действовать объектами инвентаря на другие объекты сцены или инвентаря.
Игроку доступны объекты, доступные на любой сцене -- //инвентарь//. Игрок может взаимодействовать с объектами инвентаря и действовать объектами инвентаря на другие объекты сцены или инвентаря.
<WRAP center round info>
Следует отметить, что понятие инвентаря является условным. Например, в "инвентаре" могут находиться такие объекты как "открыть", "осмотреть", "использовать" и т.д.
</WRAP>
Действиями игрока могут быть:
//Действиями// игрока могут быть:
* осмотр сцены;
* действие на объект сцены;
@ -23,21 +27,26 @@
* действие объектом сцены на инвентарь (режим scene_use);
* переход в другую сцену;
Игра представляет из себя каталог, в котором должен находиться скрипт main.lua. Другие ресурсы игры (скрипты на lua, графика и музыка) должны находиться в рамках этого каталога. Все ссылки на ресурсы делаются относительно текущего каталога -- каталога игры.
Игра представляет из себя каталог, в котором должен находиться скрипт ''main.lua''. Другие ресурсы игры (скрипты на ''lua'', графика и музыка) должны находиться в рамках этого каталога. Все ссылки на ресурсы делаются относительно текущего каталога -- каталога игры.
В начале файла main.lua может быть определен заголовок, состоящий из тегов. Теги должны начинаться с символов '--': комментарий с точки зрения lua. На данный момент существует один тег: $Name:, который должен содержать название игры в кодировке UTF8. Пример использования тега:
В начале файла ''main.lua'' может быть определен заголовок, состоящий из тегов. Теги должны начинаться с символов ''--'': комментарий с точки зрения lua. На данный момент существует один тег: ''$Name:'', который должен содержать название игры в кодировке UTF-8. Пример использования тега:
<code lua>
-- $Name: Самая интересная игра!$
</code>
Сразу после заголовков вам необходимо указать версию STEAD API, которая требуется игре. На данный момент последняя версия 1.4.0.
Сразу после заголовков вам необходимо указать версию STEAD API, которая требуется игре. На данный момент последняя версия **1.4.0**.
<code lua>
instead_version "1.4.0"
</code>
Если version отсутствует, то STEAD API будет работать в режиме совместимости (устаревшее API).
<WRAP center round important>
__Важно!__
Инициализацию игры следует описывать в функции init:
Если version отсутствует, то STEAD API будет работать в режиме совместимости (устаревшее API).
</WRAP>
//Инициализацию// игры следует описывать в функции ''init'':
<code lua>
function init()
me()._know_truth = false
@ -46,43 +55,48 @@ function init()
end
</code>
Графический интерпретатор ищет доступные игры в каталоге games. Unix версия интерпретатора кроме этого каталога просматривает также игры в каталоге ~/.instead/games.
Windows версия: Documents and Settings/USER/Local Settings/Application Data/instead/games.
В Windows и standalone Unix версии игры ищутся в каталоге ./appdata/games, если он существует.
Графический интерпретатор ищет доступные игры в каталоге ''games''. Unix-версия интерпретатора кроме этого каталога просматривает также игры в каталоге ''~/.instead/games''.
Windows-версия: ''Documents and Settings/USER/Local Settings/Application Data/instead/games''.
В Windows- и standalone-Unix-версии игры ищутся в каталоге ''./appdata/games, если он существует''.
===== 1. Сцена =====
Сцена -- это единица игры, в рамках которой игрок может изучать все объекты сцены и взаимодействовать с ними. В игре должна быть хотя бы одна сцена с именем main.
//Сцена// -- это единица игры, в рамках которой игрок может изучать все объекты сцены и взаимодействовать с ними. В игре должна быть хотя бы одна сцена с именем ''main''.
<code lua>
main = room {
nam = 'главная комната',
dsc = 'Вы в большой комнате.',
};
</code>
Запись означает создание объекта main типа room. У каждого объекта игры есть атрибуты и обработчики. Например, атрибут nam (имя) является необходимым для любого объекта.
Запись означает создание объекта ''main'' типа ''room''. У каждого объекта игры есть //атрибуты// и //обработчики//. Например, атрибут ''nam'' (имя) является необходимым для любого объекта.
Атрибут nam для сцены это то, что будет заголовком сцены при ее отображении. Имя сцены также используется для ее идентификации при переходах.
Атрибут ''nam'' для сцены это то, что будет заголовком сцены при ее отображении. Имя сцены также используется для ее идентификации при переходах.
Атрибут dsc это описание статической части сцены, которое выводится один раз при входе в сцену или явном выполнении команды look.
Атрибут ''dsc'' это описание статической части сцены, которое выводится один раз при входе в сцену или явном выполнении команды ''look''.
Внимание!!! Вы можете использовать символ ; вместо , для разделения атрибутов. Например:
<WRAP center round info>
Вы можете использовать символ '';'' вместо '','' для разделения атрибутов. Например:
<code lua>
main = room {
nam = 'главная комната';
dsc = 'Вы в большой комнате.';
};
</code>
Внимание!!! Если для вашего творческого замысла необходимо, чтобы описание статической части сцены выводилось каждый раз, вы можете определить для своей игры параметр forcedsc (в начале игры).
</WRAP>
<WRAP center round tip>
Если для вашего творческого замысла необходимо, чтобы описание статической части сцены выводилось каждый раз, вы можете определить для своей игры параметр ''forcedsc'' (в начале игры).
<code lua>
game.forcedsc = true;
</code>
Или, аналогично, задать атрибут forcedsc для конкретных сцен.
</WRAP>
Для длинных описаний удобно использовать запись вида:
<code lua>dsc = [[ Очень длинное описание... ]],</code>
При этом переводы строк игнорируются. Если вы хотите, чтобы в выводе описания сцены присутствовали абзацы -- используйте символ ^.
При этом переводы строк игнорируются. Если вы хотите, чтобы в выводе описания сцены присутствовали абзацы -- используйте символ ''^''.
<code lua>
dsc = [[ Первый абзац. ^^
@ -94,7 +108,7 @@ dsc = [[ Первый абзац. ^^
===== 2. Объекты =====
Объекты -- это единицы сцены, с которыми взаимодействует игрок.
//Объекты// -- это единицы сцены, с которыми взаимодействует игрок.
<code lua>
tabl = obj {
nam = 'стол',
@ -102,19 +116,22 @@ tabl = obj {
act = 'Гм... Просто стол...',
};
</code>
Имя объекта nam используется при попадании его в инвентарь а также в текстовом интерпретаторе для адресации объекта.
Имя объекта ''nam'' используется при попадании его в инвентарь а также в текстовом интерпретаторе для адресации объекта.
dsc -- описатель объекта. Он будет выведен в динамической части сцены. Фигурными скобками отображается фрагмент текста, который будет являться ссылкой в графическом интерпретаторе.
''dsc'' -- описание объекта. Оно будет выведено в динамической части сцены. Фигурными скобками отображается фрагмент текста, который будет являться ссылкой в графическом интерпретаторе.
act -- это обработчик, который вызывается при действии пользователя (действие на объект сцены). Его задача -- возвращение строки текста, которая станет частью событий сцены, или логического значения (см. раздел 5).
''act'' -- это обработчик, который вызывается при действии пользователя (действие на объект сцены). Его задача -- возвращение строки текста, которая станет частью событий сцены, или логического значения (см. раздел 5).
<WRAP center round important>
ВНИМАНИЕ: в пространстве имен //lua// уже существуют некоторые объекты (таблицы), например: //table//, //io//, //string//... Будьте внимательны при создании объекта. Например, в приведенном примере используется ''tabl'', а не ''table''. Лучше не использовать подобные названия, хотя в новых версиях INSTEAD эта проблема во многом решена.
</WRAP>
ВНИМАНИЕ: в пространстве имен lua уже существуют некоторые объекты (таблицы), например: table, io, string... Будьте внимательны, при создании объекта. Например, в приведенном примере используется tabl, а не table. Правда, в новых версиях INSTEAD эта проблема во многом решена.
===== 3. Добавляем объекты в сцену =====
Ссылкой на объект называется текстовая строка, содержащая имя объекта при его создании. Например: 'tabl' -- ссылка на объект tabl.
//Ссылкой// на объект называется текстовая строка, содержащая имя объекта при его создании. Например: 'tabl' -- ссылка на объект ''tabl''.
Для того, чтобы поместить в сцену объекты, нужно определить массив obj, состоящий из ссылок на объекты:
Для того, чтобы поместить в сцену объекты, нужно определить массив ''obj'', состоящий из ссылок на объекты:
<code lua>
main = room {
nam = 'главная комната',
@ -122,13 +139,16 @@ main = room {
obj = { 'tabl' },
};
</code>
Теперь, при отображении сцены мы увидим объект стол в динамической части.
Теперь, при отображении сцены мы увидим объект //"стол"// в динамической части.
Внимание!!! Вы можете использовать ссылки на объекты без кавычек в том случае, если объект был определен ранее, но использование кавычек всегда безопасней.
<WRAP center round info>
Вы можете использовать ссылки на объекты без кавычек в том случае, если объект был определен ранее, но использование кавычек всегда безопасней.
</WRAP>
===== 4. Объекты связанные с объектами =====
Объекты тоже могут содержать атрибут obj. При этом, список будет последовательно разворачиваться. Например, поместим на стол яблоко.
===== 4. Объекты, связанные с другими объектами =====
Объекты тоже могут содержать атрибут ''obj''. При этом, список будет последовательно разворачиваться. Например, поместим на стол //яблоко//.
<code lua>
apple = obj {
nam = 'яблоко',
@ -143,12 +163,12 @@ tabl = obj {
obj = { 'apple' },
};
</code>
При этом, в описании сцены мы увидим описание объектов стол и яблоко, так как apple -- связанный с tabl объект.
При этом, в описании сцены мы увидим описание объектов //стол// и //яблоко//, так как ''apple'' -- связанный с ''tabl'' объект.
===== 5. Атрибуты и обработчики как функции =====
Большинство атрибутов и обработчиков могут быть также функциями. Так, например:
Большинство атрибутов и обработчиков могут быть //функциями//. Так, например:
<code lua>
nam = function()
return 'яблоко';
@ -156,13 +176,17 @@ end,
</code>
Это синоним записи: nam = 'яблоко';
Обработчик должен вернуть строку. Если вам удобнее, для возвращения текста вы можете использовать функции:
Обработчик должен вернуть //строку//. Если вам удобнее, для возвращения текста вы можете использовать функции:
* p ("текст") -- вывод текста и пробела;
* pn ("текст") -- вывод текста с переводом строки;
* pr ("текст") -- вывод текста как есть;
* ''p ("текст")'' -- вывод текста и пробела;
* ''pn ("текст")'' -- вывод текста с переводом строки;
* ''pr ("текст")'' -- вывод текста как есть;
Если p/pn/pr вызывается с одним текстовым параметром, то скобки можно опускать. Используйте .. или , для склейки строк. Например:
<WRAP center round tip>
Если ''p''/''pn''/''pr'' вызывается с одним текстовым параметром, то скобки можно опускать.
</WRAP>
Используйте ''..'' или '','' для склейки строк. Например:
<code lua>
pn "Нет скобкам!";
@ -191,11 +215,11 @@ apple = obj {
end,
};
</code>
Если атрибут или обработчик оформлен как функция, то обычно первый аргумент функции (s) сам объект.
Если атрибут или обработчик оформлен как функция, то обычно //первый аргумент// функции (''s'') -- сам объект.
В данном примере, при показе сцены будет в динамической части сцены будет текст: 'На столе что-то лежит'. При взаимодействии с 'что-то', переменная `_seen` объекта apple будет установлена в true и мы увидим, что это было яблоко.
В данном примере при показе сцены в динамической части сцены будет выведен текст: 'На столе что-то лежит'. При взаимодействии с 'что-то', переменная ''_seen'' объекта ''apple'' будет установлена в ''true'' и мы увидим, что это было яблоко.
Запись `s._seen` означает, что переменная `_seen` размещена в объекте s (то-есть apple). Подчеркивание означает, что эта переменная попадет в файл сохранения игры.
Запись ''s._seen'' означает, что переменная ''_seen'' размещена в объекте ''s'' (то-есть ''apple''). //Подчеркивание// означает, что эта переменная //попадет в файл сохранения// игры.
Начиная с версии 1.2.0 вы можете определять переменные следующим образом:
@ -219,7 +243,10 @@ main = room {
end;
</code>
Внимание!!! Переменные записываются в файл сохранения, если они размещены в одном из перечисленных типов объектов: комната, объект, игра, игрок, глобальное пространство, при этом начинаются с символа _ или определены с помощью var и global.
<WRAP center round important>
Переменные записываются в файл сохранения, если они размещены в одном из перечисленных типов объектов: комната, объект, игра, игрок, глобальное пространство, при этом начинаются с символа ''_'' или определены с помощью ''var'' и ''global''.
</WRAP>
Начиная с версии 1.2.0 вы можете определять функции следующим образом:
<code lua>
@ -232,14 +259,14 @@ main = room {
]],
</code>
При этом в self записан текущий объект, arg1 .. arg9 и массив args[] -- параметры.
При этом в ''self'' записан текущий объект, ''arg1 ... arg9'' и массив ''args[]'' -- параметры.
В файл сохранения могут быть записаны:
* строки;
* булевы величины;
* числовые величины;
* ссылки на объекты;
* конструкции code;
* конструкции ''code'';
Иногда может понадобиться обработчик, который совершал бы некоторое действие, но не выводил никакого описания. Например:
<code lua>
@ -260,11 +287,11 @@ r12 = room {
obj = {'button'}
}
</code>
В данном случае обработчик `act` нужен для того, чтобы поменять описание комнаты, и не нужно, чтобы чтобы он выводил результат действия. Для отключения результата можно вернуть из обработчика значение true -- это будет означать, что действие успешно выполнено, но не требует дополнительного описания.
В данном случае обработчик ''act'' нужен для того, чтобы поменять описание комнаты, и не нужно, чтобы чтобы он выводил результат действия. Для отключения результата можно вернуть из обработчика значение ''true'' -- это будет означать, что действие успешно выполнено, но не требует дополнительного описания.
Если необходимо показать, что действие невыполнимо, ничего не возвращайте. При этом будет отображено описание по умолчанию, заданное с помощью обработчика `game.act`. Обычно описание по умолчанию содержит описание невыполнимых действий.
Если необходимо показать, что действие невыполнимо, ничего не возвращайте. При этом будет отображено описание по умолчанию, заданное с помощью обработчика ''game.act''. Обычно описание по умолчанию содержит описание невыполнимых действий.
Обратите внимание, что для создания динамического описания сцены в рассмотренном выше примере использовалось новая переменная _dynamic_dsc. Это сделано для того, чтобы изменённое описание попало в файл сохранения игры. Поскольку имя ''dsc'' не начинается с подчёркивания или заглавной буквы, по умолчанию оно не попадёт в файл сохранения.
Обратите внимание, что для создания динамического описания сцены в рассмотренном выше примере использовалось новая переменная ''_dynamic_dsc''. Это сделано для того, чтобы изменённое описание попало в файл сохранения игры. Поскольку имя ''dsc'' не начинается с подчёркивания или заглавной буквы, по умолчанию оно не попадёт в файл сохранения.
Данный пример мог бы выглядеть более разумно:
<code lua>
@ -291,7 +318,7 @@ r12 = room {
===== 6. Инвентарь =====
Простейший вариант сделать объект, который можно брать -- определить обработчик tak.
Простейший вариант сделать объект, который можно брать -- определить обработчик ''tak''.
Например:
<code lua>
@ -305,13 +332,13 @@ apple = obj {
tak = 'Вы взяли яблоко.',
};
</code>
При этом, при действии игрока на объект яблоко -- яблоко будет убрано из сцены и добавлено в инвентарь. При действии игрока на инвентарь -- вызывается обработчик inv.
При этом, при действии игрока на объект "яблоко" -- яблоко будет убрано из сцены и добавлено в инвентарь. При действии игрока на инвентарь -- вызывается обработчик ''inv''.
В нашем примере -- при действии игроком на яблоко в инвентаре - яблоко будет съедено.
В нашем примере, при действии игроком на яблоко в инвентаре -- яблоко будет съедено.
===== 7. Переходы между сценами =====
Для перехода между сценами используется атрибут сцены -- список way.
Для перехода между сценами используется атрибут сцены -- список ''way''.
<code lua>
room2 = room {
nam = 'зал',
@ -327,9 +354,9 @@ main = room {
way = { 'room2' },
};
</code>
При этом, вы сможете переходить между сценами main и room2. Как вы помните, nam может быть функцией, и вы можете генерировать имена сцен на лету, например, если вы хотите, чтобы игрок не знал название сцены, пока не попал на нее.
При этом, вы сможете переходить между сценами ''main'' и ''room2''. Как вы помните, ''nam'' может быть функцией, и вы можете генерировать имена сцен на лету, например, если вы хотите, чтобы игрок не знал название сцены, пока не попал на нее.
При переходе между сценами движок вызывает обработчик exit из текущей сцены и enter в той сцены, куда идет игрок. Например:
При переходе между сценами движок вызывает обработчик ''exit'' из текущей сцены и ''enter'' в той сцены, куда идет игрок. Например:
<code lua>
room2 = room {
enter = 'Вы заходите в зал.',
@ -340,7 +367,7 @@ room2 = room {
};
</code>
exit и enter могут быть функциями. Тогда первый параметр это (как всегда) сам объект, а второй это комната куда игрок хочет идти (для exit) или из которой уходит (для enter). Например:
''exit'' и ''enter'' могут быть функциями. Тогда первый параметр это (как всегда) //сам объект//, а второй это комната куда игрок //хочет идти// (для ''exit'') или из которой //уходит// (для ''enter''). Например:
<code lua>
room2 = room {
enter = function(s, f)
@ -358,9 +385,9 @@ room2 = room {
end,
};
</code>
Как видим, обработчики могут возвращать два значения: строку и статус. В нашем примере функция exit вернет false, если игрок попытается уйти из зала в main комнату. false означает, что переход не будет выполнен. Такая же логика работает и для enter. Кроме того, она работает и для обработчика tak.
Как видим, обработчики могут возвращать два значения: //строку// и //статус//. В нашем примере функция ''exit'' вернет ''false'', если игрок попытается уйти из зала в комнату ''main''. ''false'' означает, что переход //не будет// выполнен. Такая же логика работает и для ''enter''. Кроме того, она работает и для обработчика ''tak''.
Если вы используете функции p/pn/pr, то просто возвращайте статус операции с помощью return:
Если вы используете функции ''p''/''pn''/''pr'', то просто возвращайте статус операции с помощью ''return'':
<code lua>
room2 = room {
enter = function(s, f)
@ -380,11 +407,14 @@ room2 = room {
};
</code>
Следует отметить, что при вызове обработчика enter текущая сцена может быть еще не изменена!!! Начиная с версии 1.2.0 добавлены обработчики left и entered, которые вызываются после того, как переход произошел. Эти обработчики рекомендованы к использованию всегда, когда нет необходимости запрещать переход.
<WRAP center round important>
Следует отметить, что при вызове обработчика enter текущая сцена может быть **еще не изменена**!!! Начиная с версии 1.2.0 добавлены обработчики left и entered, которые вызываются после того, как переход произошел. Эти обработчики рекомендованы к использованию всегда, когда нет необходимости запрещать переход.
</WRAP>
===== 8. Действие объектов друг на друга =====
Игрок может действовать объектом инвентаря на другие объекты. При этом вызывается обработчик use у объекта которым действуют и used -- на которого действуют.
Игрок может действовать объектом инвентаря на другие объекты. При этом вызывается обработчик ''use'' у объекта, которым действуют, и ''used'' -- на который действуют.
Например:
<code lua>
@ -404,10 +434,9 @@ tabl = obj {
used = 'Вы пытаетесь сделать что-то со столом...',
};
</code>
Если игрок возьмет нож и использует его на стол -- то увидит текст обработчиков use и used. use и used могут быть функциями. Тогда первый параметр это сам объект,
а второй -- объект на который направлено действие в случае use и объект, которым действие осуществляется в случае used.
Если игрок возьмет нож и использует его на стол -- то он увидит текст обработчиков ''use'' и ''used''. ''use'' и ''used'' могут быть функциями. Тогда //первый// параметр это //сам объект//, а //второй// -- объект на который //направлено действие// в случае ''use'' и объект, которым действие //осуществляется// в случае ''used''.
use может вернуть статус false, в этом случае обработчик used не вызовется (если он вообще был). Статус обработчика used -- игнорируется.
''use'' может вернуть статус ''false'', в этом случае обработчик ''used'' не вызовется (если он вообще был). Статус обработчика ''used'' **игнорируется**.
Пример:
<code lua>
@ -426,11 +455,11 @@ knife = obj {
end
};
</code>
Нож можно использовать только на стол.
В примере выше нож можно использовать только на стол.
===== 9. Объект игрок =====
===== 9. Объект "игрок" =====
Игрок в STEAD представлен объектом pl. Тип объекта -- player. В движке объект создается следующим образом:
Игрок в STEAD представлен объектом ''pl''. Тип объекта -- ''player''. В движке объект создается следующим образом:
<code lua>
pl = player {
nam = "Incognito",
@ -438,11 +467,11 @@ pl = player {
obj = { }
};
</code>
Атрибут obj представляет собой инвентарь игрока.
Атрибут ''obj'' представляет собой инвентарь игрока.
===== 10. Объект game =====
===== 10. Объект ''game'' =====
Игра также представлена объектом game с типом game. В движке он определяется следующим образом:
Игра также представлена объектом ''game'' с типом ''game''. В движке он определяется следующим образом:
<code lua>
game = game {
nam = "INSTEAD -- Simple Text Adventure interpreter v"..version.." '2009 by Peter Kosyh",
@ -454,36 +483,44 @@ Commands:^
showlast = true,
};
</code>
Как видим, объект хранит в себе указатель на текущего игрока ('pl') и некоторые параметры. Например, вы можете указать в начале своей игры кодировку текста следующим образом:
<code> game.codepage="UTF-8"; </code>
Как видим, объект хранит в себе указатель на текущего игрока (''pl'') и некоторые параметры. Например, вы можете указать в начале своей игры кодировку текста следующим образом:
<code lua>game.codepage="UTF-8"; </code>
Поддержка произвольных кодировок изначально присутствует в UNIX версии интерпретатора, в windows версии -- начиная с 0.7.7.
Кроме того, объект game может содержать обработчики по умолчанию act, inv, use, которые будут вызваны, если в результате действий пользователя не будут найдены никакие другие обработчики. Например, вы можете написать в начале игры:
Кроме того, объект ''game'' может содержать обработчики по умолчанию ''act'', ''inv'', ''use'', которые будут вызваны, если в результате действий пользователя не будут найдены никакие другие обработчики. Например, вы можете написать в начале игры:
<code lua>
game.act = 'Не получается.';
game.inv = 'Гм.. Странная штука..';
game.use = 'Не сработает...';
</code>
===== 11. Атрибуты - списки =====
===== 11. Атрибуты-списки =====
Атрибуты списки (такие как way или obj) позволяют работать с собой, таким образом позволяя реализовать динамически определяемые переходы между сценами, живые объекты и т.д.
Атрибуты-списки (такие как ''way'' или ''obj'') позволяют работать с собой, таким образом позволяя реализовать динамически определяемые переходы между сценами, живые объекты и т.д.
Методы списков: add, del, look, srch, purge, replace. Из них наиболее часто используемые: add и del.
Методы списков: ''add'', ''del'', ''look'', ''srch'', ''purge'', ''replace''. Из них наиболее часто используемые: ''add'' и ''del''.
add - добавляет в список. del -- удаляет из него. purge -- удаляет даже выключенный объект. srch -- выполняет поиск объекта. replace -- замена объекта. Следует отметить, что параметром del, purge, replace и srch может быть не только сам объект или идентификатор объекта, но и имя объекта.
* ''add'' - добавляет в список.
* ''del'' -- удаляет из него.
* ''purge'' -- удаляет даже выключенный объект.
* ''srch'' -- выполняет поиск объекта.
* ''replace'' -- замена объекта.
Начиная с версии 0.8 параметром add может быть сам объект. Кроме того, с этой версии добавляется необязательный второй параметр -- позиция в списке. Начиная с версии 0.8 вы можете также выполнять модификацию списка по индексу с помощью метода set. Например:
<WRAP center round info>
Следует отметить, что параметром ''add'', ''del'', ''purge'', ''replace'' и ''srch'' может быть не только сам объект или идентификатор объекта, но и имя объекта.
</WRAP>
Начиная с версии 0.8 параметром ''add'' может быть сам объект. Кроме того, с этой версии добавляется необязательный второй параметр -- позиция в списке. Начиная с версии 0.8 вы можете также выполнять модификацию списка по индексу с помощью метода ''set''. Например:
<code lua>
objs():set('knife',1);
</code>
Выше, вы уже видели пример со съеденным яблоком, там использовалась конструкция inv():del('apple');
Выше, вы уже видели пример со съеденным яблоком, там использовалась конструкция ''inv():del('apple')'';
inv() -- это функция, которая возвращает список инвентаря. del после ':'-- метод, удаляющий элемент инвентаря.
''inv()'' -- это функция, которая возвращает список инвентаря. ''del'' после '':'' -- метод, удаляющий элемент инвентаря.
Аналогично, собственная реализация tak может быть такой:
Аналогично, собственная реализация ''tak'' может быть такой:
<code lua>
knife = obj {
nam = 'нож',
@ -496,30 +533,32 @@ knife = obj {
};
</code>
Кроме добавления, удаления объектов из списков вы можете использовать выключение/включение объектов с помощью методов enable() и disable(). Например: knife:disable(). При этом объект knife пропадает из описания сцены, но в последствии может быть опять быть включен, с помощью knife:enable().
Кроме добавления, удаления объектов из списков вы можете использовать //выключение/включение// объектов с помощью методов ''enable()'' и ''disable()''. Например: ''knife:disable()''. При этом объект ''knife'' пропадает из описания сцены, но в последствии может быть опять быть включен, с помощью ''knife:enable()''.
Начиная с версии 0.9.1 доступны методы zap и cat. zap() -- обнуляет список. cat(b, [pos]) -- добавляет в список содержимое b на позицию pos.
Начиная с версии 0.9.1 доступны методы ''zap()'' и ''cat()''. ''zap()'' -- обнуляет список. ''cat(b, [pos])'' -- добавляет в список содержимое ''b'' на позицию ''pos''.
Начиная с версии 0.9.1 доступны методы disable_all и enable_all, выключающие и включающие вложенные в объект объекты.
Начиная с версии 0.9.1 доступны методы ''disable_all()'' и ''enable_all()'', выключающие и включающие вложенные в объект объекты.
Внимание!!! На данный момент для работы с инвентарем и объектами рекомендуется использовать более высокоуровневые функции: put/get/take/drop/remove/seen/have и др.
<WRAP center round important>
Внимание!!! На данный момент для работы с инвентарем и объектами рекомендуется использовать более высокоуровневые функции: ''put''/''get''/''take''/''drop''/''remove''/''seen''/''have'' и др.
</WRAP>
===== 12. Функции, которые возвращают объекты =====
В STEAD определены некоторые функции, которые возвращают наиболее часто используемые объекты. Например:
* inv() возвращает список инвентаря;
* objs() возвращает список объектов текущей сцены; (начиная с 0.8.5 -- необязательный параметр -- сцена, для которой возвращается список);
* ways() возвращает список возможных переходов из текущей сцены; (начиная с 0.8.5 -- необязательный параметр -- сцена, для которой возвращается список);
* me() возвращает объект-игрок;
* here() возвращает объект текущую сцену; (начиная с 0.8.5 -- еще одна функция where(obj) -- возвращает сцену на которой находится объект, если он был помещен туда с помощью put/move/drop)
* from() возвращает объект прошлой сцены;
* seen(obj, [scene]) возвращает объект, если он присутствует и не отключен на сцене, есть второй необязательный параметр -- сцена;
* have(obj, [scene]) возвращает объект, если он есть в инвентаре и не отключен, есть второй необязательный параметр -- сцена;
* exist(obj, [scene]) возвращает объект, если он присутствует на сцене, есть второй необязательный параметр -- сцена;
* live(obj) возвращает объект, если он присутствует среди живых объектов;
* path(объект,[комната]) найти элемент в way, даже если он disabled;
* ''inv()'' возвращает список инвентаря;
* ''objs()'' возвращает список объектов текущей сцены; (начиная с 0.8.5 -- необязательный параметр -- сцена, для которой возвращается список);
* ''ways()'' возвращает список возможных переходов из текущей сцены; (начиная с 0.8.5 -- необязательный параметр -- сцена, для которой возвращается список);
* ''me()'' возвращает объект-игрок;
* ''here()'' возвращает объект текущую сцену; (начиная с 0.8.5 -- еще одна функция ''where(obj)'' -- возвращает сцену на которой находится объект, если он был помещен туда с помощью ''put/move/drop'')
* ''from()'' возвращает объект прошлой сцены;
* ''seen(obj, [scene])'' возвращает объект, если он присутствует и не отключен на сцене, есть второй необязательный параметр -- сцена;
* ''have(obj, [scene])'' возвращает объект, если он есть в инвентаре и не отключен, есть второй необязательный параметр -- сцена;
* ''exist(obj, [scene])'' возвращает объект, если он присутствует на сцене, есть второй необязательный параметр -- сцена;
* ''live(obj)'' возвращает объект, если он присутствует среди живых объектов;
* ''path(объект,[комната])'' найти элемент в ''way'', даже если он ''disabled'';
Комбинируя эти функции с методами add, del можно динамически менять сцену, например:
Комбинируя эти функции с методами ''add'', ''del'' можно динамически менять сцену, например:
<code lua>
ways():add('nextroom'); -- добавить переход на новую сцену;
</code>
@ -528,9 +567,9 @@ objs():add('chair'); -- добавить объект в текущую сцен
</code>
Еще одна функция, которая получает объект по ссылке:
**ref()**.
''ref()''.
Например, мы можем добавить объект в локацию 'home' следующим образом:
Например, мы можем добавить объект в локацию ''home'' следующим образом:
<code lua>
ref('home').obj:add('chair');
</code>
@ -553,13 +592,13 @@ put('chair', 'home');
put(chair, home);
</code>
Начиная с 0.8.5 -- **deref(o)**, возвращает ссылку-строку для объекта;
Начиная с 0.8.5 -- ''deref(o)'', возвращает ссылку-строку для объекта;
===== 13. Некоторые вспомогательные функции. =====
В STEAD определены некоторые высокоуровневые функции, которые могут оказаться полезными при написании игры.
have() -- проверяет, есть ли объект в инвентаре. По объекту, его ссылке или по атрибуту nam объекта. Например:
* ''have()'' -- проверяет, есть ли объект в инвентаре. По объекту, его ссылке или по атрибуту ''nam'' объекта. Например:
<code lua>
...
act = function(s)
@ -579,17 +618,23 @@ end
</code>
В следующих примерах вы также можете использовать все варианты адресации объектов.
move(o, w) -- переносит объект из текущей сцены в другую:
* ''move(o, w)'' -- переносит объект из текущей сцены в другую:
<code lua>move('mycat','inmycar');</code>
Если вы хотите перенести объект из произвольной сцены, вам придется удалить его из старой сцены с помощью метода del. Для создания сложно перемещающихся объектов, вам придется написать свой метод, который будет сохранять текущую позицию объекта в самом объекте и делать удаление объекта из старой сцены. Вы можете указать исходную позицию (комнату) объекта в качестве третьего параметра move.
<WRAP center round info>
Если вы хотите перенести объект из произвольной сцены, вам придется удалить его из старой сцены с помощью метода ''del''. Для создания сложно перемещающихся объектов, вам придется написать свой метод, который будет сохранять текущую позицию объекта в самом объекте и делать удаление объекта из старой сцены.
</WRAP>
Вы можете указать исходную позицию (комнату) объекта в качестве третьего параметра ''move''.
<code lua>move('mycat','inmycar', 'forest'); </code>
Начиная с версии 0.8 присутствует также функция movef, аналогичная move, но добавляющая объект в начало списка.
<WRAP center round info>
Начиная с версии 0.8 присутствует также функция ''movef'', аналогичная ''move'', но добавляющая объект в начало списка.
</WRAP>
seen(o) -- если объект присутствует в текущей сцене:
* ''seen(o)'' -- если объект присутствует в текущей сцене:
<code lua>
if seen('mycat') then
move('mycat','inmycar');
@ -597,25 +642,27 @@ end
</code>
Начиная с 0.8.6 -- необязательный второй параметр -- сцена.
drop(o) -- положить объект из инвентаря на сцену:
* ''drop(o)'' -- положить объект из инвентаря на сцену:
<code lua>
drop('knife');
</code>
<WRAP center round info>
Начиная с версии 0.8 присутствует также функция ''dropf'', аналогичная ''drop'', но добавляющая объект в начало списка. Начиная с версии 0.8.5 второй необязательный параметр -- комната, куда помещается предмет. Кроме того, для версий >=0.8.5 доступны похожие функции ''put''/''putf'', которые не удаляют предмет из инвентаря.
drop('knife');
Начиная с 0.8.9 -- присутствует функция ''remove(o, [from])'', удаляет объект из текущей сцены или сцены ''from''.
</WRAP>
Начиная с версии 0.8 присутствует также функция dropf, аналогичная drop, но добавляющая объект в начало списка. Начиная с версии 0.8.5 второй необязательный параметр -- комната, куда помещается предмет. Кроме того, для версий >=0.8.5 доступны похожие функции put/putf, которые не удаляет предмет из инвентаря.
Начиная с 0.8.9 -- присутствует функция remove(o, [from]), удаляет объект из текущей сцены или сцены from.
take(o) -- взять объект.
* ''take(o)'' -- взять объект.
<code lua>
take('knife');
</code>
<WRAP center round info>
Начиная с версии 0.8.5 второй необязательный параметр -- комната, с которой берется предмет.
</WRAP>
taken(o) -- если объект взят -- вернет true (взят с помощью tak или take());
rnd(m) -- случайное значение от 1 до m.
goto(w) -- перейти в сцену w, при этом, если вы не используете p/pn/pr обработчику нужно вернуть возвращаемое значение goto. Например:
* ''taken(o)'' -- если объект взят -- вернет ''true'' (взят с помощью ''tak'' или ''take()'');
* ''rnd(m)'' -- случайное значение от ''1'' до ''m''.
* ''goto(w)'' -- перейти в сцену ''w'', при этом, если вы не используете ''p''/''pn''/''pr'' обработчику нужно вернуть возвращаемое значение ''goto''. Например:
<code lua>
act = code [[
pn "Я иду в следующую комнату..."
@ -626,8 +673,12 @@ act = code [[
return cat('Я иду в следующую комнату', goto (nextroom));
]]
</code>
Внимание!!! После вызова goto выполнение обработчика продолжится до его завершения.
change_pl(p) -- переключиться на другого игрока (со своим инвентарем и позицией). При этом функция возвращает описание сцены нового игрока и это возвращаемое значение должно быть передано из обработчика (см. goto()).
<WRAP center round important>
**Внимание!!!**
После вызова ''goto'' выполнение обработчика продолжится до его завершения.
</WRAP>
* ''change_pl(p)'' -- переключиться на другого игрока (со своим инвентарем и позицией). При этом функция возвращает описание сцены нового игрока и это возвращаемое значение должно быть передано из обработчика (см. ''goto()'').
<code lua>
mycar = obj {
@ -638,37 +689,23 @@ mycar = obj {
end
};
</code>
goback() -- возвращается из сцены в прошлую.
back() -- возвращается из сцены в прошлую. Если это переход из диалога в комнату, то не вызываются: dsc, enter, entered у комнаты. exit/left диалога вызываются. В других случаях аналогична goback.
goin(комната) -- перейти в сцену, при этом exit/left текущей комнаты не вызывается;
goout() -- вернуться в прошлую сцену, при этом enter/entered этой сцены не вызовется;
time() -- возвращает текущее время игры. Время игры считается в активных действиях.
cat(...) -- возвращает строку -- склейку строк-аргументов. Если первый аргумент nil, то функция возвращает nil.
par(...) -- возвращает строку -- склейку строк-аргументов, разбитых строкой-первым параметром.
disable/enable/disable_all/enable_all -- аналог одноименных методов у объекта;
visited([комната]) -- счетчик посещений комнаты или nil;
path(объект,[комната]) -- найти элемент в way, даже если он disabled;
nameof(объект) -- вернуть имя объекта (nam атрибут);
purge (объект, [откуда]) -- см. remove, удаляет даже выключенные объекты;
replace(объект, на объект, [где]) -- замена одного объекта другим;
disabled(объект) -- возвращает true, если объект отключен;
* ''goback()'' -- возвращается из сцены в прошлую.
* ''back()'' -- возвращается из сцены в прошлую. Если это переход из диалога в комнату, то не вызываются: ''dsc'', ''enter'', ''entered'' у комнаты. ''exit''/''left'' диалога вызываются. В других случаях аналогична ''goback''.
* ''goin(комната)'' -- перейти в сцену, при этом ''exit''/''left'' текущей комнаты не вызывается;
* ''goout()'' -- вернуться в прошлую сцену, при этом ''enter''/''entered'' этой сцены не вызовется;
* ''time()'' -- возвращает текущее время игры. Время игры считается в активных действиях.
* ''cat(...)'' -- возвращает строку -- склейку строк-аргументов. Если первый аргумент ''nil'', то функция возвращает ''nil''.
* ''par(...)'' -- возвращает строку -- склейку строк-аргументов, разбитых строкой-первым параметром.
* ''disable''/''enable''/''disable_all''/''enable_all'' -- аналог одноименных методов у объекта;
* ''visited([комната])'' -- счетчик посещений комнаты или ''nil'';
* ''path(объект,[комната])'' -- найти элемент в ''way'', даже если он ''disabled'';
* ''nameof(объект)'' -- вернуть имя объекта (''nam'' атрибут);
* ''purge (объект, [откуда])'' -- см. ''remove'', удаляет даже выключенные объекты;
* ''replace(объект, на объект, [где])'' -- замена одного объекта другим;
* ''disabled(объект)'' -- возвращает ''true'', если объект отключен;
===== 14. Диалоги =====
Диалоги это сцены, содержащие объекты -- фразы. Например, простейший диалог может выглядеть следующим образом.
//Диалоги// -- это сцены, содержащие объекты -- фразы. Например, простейший диалог может выглядеть следующим образом:
<code lua>
povardlg = dlg {
nam = 'на кухне',
@ -681,7 +718,7 @@ povardlg = dlg {
},
};
</code>
phr -- создание фразы. Фраза содержит вопрос, ответ и реакцию (реакция в данном примере отсутствует). Когда игрок выбирает одну из фраз, фраза отключается. Когда все фразы отключатся диалог заканчивается. Реакция -- это строка кода на lua который выполнится после отключения фразы. Например:
''phr'' -- создание фразы. Фраза содержит //вопрос//, //ответ// и //реакцию// (реакция в данном примере отсутствует). Когда игрок выбирает одну из фраз, фраза отключается. Когда все фразы отключатся диалог заканчивается. //Реакция// -- это строка кода на lua, который выполнится после отключения фразы. Например:
<code lua>
food = obj {
nam = 'еда',
@ -712,13 +749,13 @@ povardlg = dlg {
В реакции может быть любой lua код, но в STEAD определены наиболее часто используемые функции:
* pon(n..) -- включить фразы диалога с номерами n... (в нашем примере -- чтобы игрок мог повторно взять еду того-же вида).
* poff(n...) -- выключить фразы диалога с номерами n...
* prem(n...) -- удалить (заблокировать) фразы диалога с номерами n... (удаление означает невозможность включения фраз. pon(n..) не приведет к включению фраз).
* pseen(n..) -- вернет true, если все заданные фразы диалога видимы.
* punseen(n..) -- вернет true, если все заданные фразы диалога невидимы.
* ''pon(n..)'' -- включить фразы диалога с номерами n... (в нашем примере -- чтобы игрок мог повторно взять еду того-же вида).
* ''poff(n...)'' -- выключить фразы диалога с номерами n...
* ''prem(n...)'' -- удалить (заблокировать) фразы диалога с номерами n... (удаление означает невозможность включения фраз. ''pon(n..)'' не приведет к включению фраз).
* ''pseen(n..)'' -- вернет ''true'', если все заданные фразы диалога видимы.
* ''punseen(n..)'' -- вернет ''true'', если все заданные фразы диалога невидимы.
Если параметр n не указан, действие относится к текущей фразе.
Если параметр ''n'' не указан, действие относится к текущей фразе.
Переход в диалог осуществляется как переход на сцену:
<code lua>
@ -755,9 +792,12 @@ facectrl = dlg {
};
</code>
`_phr` -- создает выключенную фразу, которую можно включить. Данный пример показывает также возможность использования методов pon, poff, prem для диалога (см. exit).
''_phr'' -- создает выключенную фразу, которую можно включить. Данный пример показывает также возможность использования методов ''pon'', ''poff'', ''prem'' для диалога (см. ''exit'').
<WRAP center round tip>
Вы можете включать/выключать/удалять/проверять фразы не только текущего, но и произвольного диалога, с помощью методов объекта диалог ''pon''/''poff''/''prem''/''pseen''/''punseen''. Например: ''shopman:pon(5);''
</WRAP>
Вы можете включать/выключать/удалять/проверять фразы не только текущего, но и произвольного диалога, с помощью методов объекта диалог pon/poff/prem/pseen/punseen. Например: shopman:pon(5);
===== 15. Облегченные объекты =====
@ -778,18 +818,18 @@ sside = room {
vobj("люди", "Время от времени дверь подъезда хлопает впуская и выпуская {людей}.")},
};
</code>
Как видим, vobj позволяет сделать легкую версию статического объекта, с которым тем не менее можно взаимодействовать (за счет определения обработчика act в сцене и анализа имени объекта). vobj также вызывает метод used, при этом в качестве третьего параметра передается объект, воздействующий на виртуальный объект.
Как видим, ''vobj'' позволяет сделать легкую версию статического объекта, с которым тем не менее можно взаимодействовать (за счет определения обработчика ''act'' в сцене и анализа имени объекта). ''vobj'' также вызывает метод ''used'', при этом в качестве третьего параметра передается объект, воздействующий на виртуальный объект.
Синтаксис vobj: vobj(имя, описатель);
Синтаксис ''vobj'': ''vobj(имя, описатель)'';
Существует модификация объекта vobj -- vway. vway реализует ссылку.
Синтаксис vway: vway(имя, описатель, сцена назначения); например:
Существует модификация объекта ''vobj'' -- ''vway''. ''vway'' реализует ссылку.
Синтаксис ''vway'': ''vway(имя, описатель, сцена назначения);'' например:
<code lua>
obj = { vway("дальше", "Нажмите {здесь}.", 'nextroom') }
</code>
Вы можете динамически заполнять сцену объектами vobj или vway с помощью методов add и del. Например:
Вы можете динамически заполнять сцену объектами ''vobj'' или ''vway'' с помощью методов ''add'' и ''del''. Например:
<code lua>
objs(home):add(vway("next", "{Дальше}.", 'next_room'));
@ -797,8 +837,8 @@ sside = room {
home.obj:del("next");
</code>
Определена также упрощенная сцена vroom.
Синтаксис: vroom(имя перехода, сцена назначения). Например:
Определена также упрощенная сцена ''vroom''.
Синтаксис: ''vroom(имя перехода, сцена назначения)''. Например:
<code lua>
home.obj:add(vroom("идти на запад", 'mountains');
@ -837,11 +877,11 @@ profdlg2 = dlg {
[[inv():add('mycat'); lifeon('mycat')]]),
....
</code>
Любой объект или сцена могут иметь свой обработчик life, который вызывается каждый раз при смене текущего времени игры, если объект или сцена были добавлены в список живых объектов с помощью lifeon. Не забывайте удалять живые объекты из списка с помощью lifeoff, когда они больше не нужны. Это можно сделать, например, в обработчике exit, или любым другим способом.
Любой объект или сцена могут иметь свой обработчик ''life'', который вызывается каждый раз при смене текущего времени игры, если объект или сцена были добавлены в список живых объектов с помощью ''lifeon''. Не забывайте удалять живые объекты из списка с помощью ''lifeoff'', когда они больше не нужны. Это можно сделать, например, в обработчике ''exit'', или любым другим способом.
life метод может возвращать текст события, который печатается после описания сцены.
''life'' метод может возвращать текст события, который печатается после описания сцены.
Начиная с версии 0.9.1 вы можете вернуть из обработчика life второй код возврата, важность. (true или false). Например:
Начиная с версии 0.9.1 вы можете вернуть из обработчика ''life'' второй код возврата, важность. (''true'' или ''false''). Например:
<code lua>
return 'В комнату вошел охранник.', true
</code>
@ -854,7 +894,7 @@ return 'В комнату вошел охранник.', true
При этом текст события будет выведен до описания объектов.
===== 17. Графика и музыка =====
Графический интерпретатор анализирует атрибут сцены pic, и воспринимает его как путь к картинке, например:
Графический интерпретатор анализирует атрибут сцены ''pic'', и воспринимает его как путь к картинке, например:
<code lua>
home = room {
@ -864,21 +904,21 @@ home = room {
};
</code>
Конечно, pic может быть функцией, расширяя возможности разработчика.
Если в текущей сцене не определен атрибут pic, то берется атрибут game.pic. Если не определен и он, то картинка не отображается.
Конечно, ''pic'' может быть функцией, расширяя возможности разработчика.
Если в текущей сцене не определен атрибут ''pic'', то берется атрибут ''game.pic''. Если не определен и он, то картинка не отображается.
Начиная с версии 0.9.2 вы можете использовать в качестве картинок анимированные gif файлы.
Начиная с версии 0.9.2 вы можете встраивать графические изображения в текст или в инвентарь с помощью функции img. Например:
Начиная с версии 0.9.2 вы можете встраивать графические изображения в текст или в инвентарь с помощью функции ''img''. Например:
<code lua>
knife = obj {
nam = 'Нож'..img('img/knife.png'),
}
</code>
А начиная с 1.3.0 поддерживается обтекание картинок текстом. Если картинка вставляется с помощью функции imgl/imgr, она будет расположена у левого/правого края. Такие картинки не могут быть ссылками.
А начиная с 1.3.0 поддерживается обтекание картинок текстом. Если картинка вставляется с помощью функции ''imgl''/''imgr'', она будет расположена у левого/правого края. Такие картинки не могут быть ссылками.
Для задания отступов вокруг изображения используйте pad, например:
Для задания отступов вокруг изображения используйте ''pad'', например:
<code lua>
imgl 'pad:16,picture.png' -- отступы по 16 от каждого края
imgl 'pad:0 16 16 4,picture.png' -- отступы: вверху 0, справа 16, внизу 16, слева 4
@ -891,7 +931,7 @@ dsc = img 'blank:32x32'..[[Строка с пустым изображением
dsc = img 'box:32x32,red,128'..[[Строка красным полупрозрачным квадратом.]];
</code>
В современной версии INSTEAD вы можете использовать атрибут disp:
В современной версии INSTEAD вы можете использовать атрибут ''disp'':
<code lua>
knife = obj {
nam = 'Нож';
@ -905,7 +945,7 @@ pic = 'gfx/mycat.png;gfx/milk.png@120,25;gfx/fish.png@32,32'
</code>
Интерпретатор проигрывает в цикле текущую музыку, которая задается с помощью функции:
set_music(имя музыкального файла).
''set_music(имя музыкального файла)''.
Например:
<code lua>
@ -919,40 +959,40 @@ street = room {
};
</code>
get_music() возвращает текущее имя трека.
''get_music()'' возвращает текущее имя трека.
Начиная с версии 0.7.7 в функцию set_music() можно передавать второй параметр -- количество проигрываний. Получить текущий счетчик можно с помощью get_music_loop. 0 - означает вечный цикл. 1..n -- количество проигрываний. -1 -- проигрывание текущего трека закончено.
Начиная с версии 0.7.7 в функцию ''set_music()'' можно передавать второй параметр -- количество проигрываний. Получить текущий счетчик можно с помощью ''get_music_loop''. 0 - означает вечный цикл. 1..n -- количество проигрываний. -1 -- проигрывание текущего трека закончено.
Начиная с версии 0.9.2 set_sound() позволяет проиграть звуковой файл. get_sound() возвращает имя звукового файла, который будет проигран.
Начиная с версии 0.9.2 ''set_sound()'' позволяет проиграть звуковой файл. ''get_sound()'' возвращает имя звукового файла, который будет проигран.
Для того, чтобы отменить проигрывание, вы можете использовать stop_music() (с версии 1.0.0).
Для того, чтобы отменить проигрывание, вы можете использовать ''stop_music()'' (с версии 1.0.0).
is_music() позволяет узнать, проигрывается ли музыка. (с версии 1.0.0)
''is_music()'' позволяет узнать, проигрывается ли музыка. (с версии 1.0.0)
===== 18. Полезные советы =====
==== Разбиение на файлы ====
Для разбиения текста игры на файлы вы можете использовать dofile. Вы должны использовать dofile в глобальном контексте таким образом, чтобы во время загрузки main.lua загрузились и все остальные фрагменты игры, например.
Для разбиения текста игры на файлы вы можете использовать ''dofile''. Вы должны использовать ''dofile'' в глобальном контексте таким образом, чтобы во время загрузки ''main.lua'' загрузились и все остальные фрагменты игры, например.
<code>
<code lua>
-- main.lua
dofile "episode1.lua"
dofile "npc.lau"
dofile "start.lua"
</code>
Для динамической подгрузки частей игры (с возможностью переопределения существующих объектов), вы можете воспользоваться gamefile:
Для динамической подгрузки частей игры (с возможностью переопределения существующих объектов), вы можете воспользоваться ''gamefile'':
<code>
<code lua>
...
act = code [[ gamefile ("episode2.lua"); ]]
...
</code>
gamefile позволяет загрузить новый файл и забыть стек предыдущих загрузок, запустив этот новый файл как самостоятельную игру.
''gamefile'' позволяет загрузить новый файл и забыть стек предыдущих загрузок, запустив этот новый файл как самостоятельную игру.
<code>
<code lua>
...
act = code [[ gamefile ("episode3.lua", true); ]]
...
@ -961,19 +1001,19 @@ act = code [[ gamefile ("episode3.lua", true); ]]
==== Модули ====
**//[[ru:gamedev:modules|Подробнее о модулях]]//**
Начиная с версии 1.2.0 появилась возможность использования модулей с помощью require. На данный момент существуют следующие модули:
Начиная с версии 1.2.0 появилась возможность использования модулей с помощью ''require''. На данный момент существуют следующие модули:
* dbg — модуль отладки (require "dbg" включить отладчик);
* goto — улучшенный вариант реализации переходов;
* xact — множественные ссылки;
* input — клавиатурный ввод;
* click — модуль перехвата кликов мыши по картинке сцены;
* vars — модуль определения переменных;
* prefs — модуль настроек;
* snapshots — модуль поддержки снапшотов;
* format — модуль оформления вывода;
* object — модуль улучшенных объектов;
* theme — управление темой;
* ''dbg'' — модуль отладки (''require "dbg"'' включить отладчик);
* ''goto'' — улучшенный вариант реализации переходов;
* ''xact'' — множественные ссылки;
* ''input'' — клавиатурный ввод;
* ''click'' — модуль перехвата кликов мыши по картинке сцены;
* ''vars'' — модуль определения переменных;
* ''prefs'' — модуль настроек;
* ''snapshots'' — модуль поддержки снапшотов;
* ''format'' — модуль оформления вывода;
* ''object'' — модуль улучшенных объектов;
* ''theme'' — управление темой;
Использование модуля выглядит так:
<code lua>
@ -983,9 +1023,9 @@ require "para"
require "dbg"
...
</code>
Следующие модули подключаются автоматически, если вы задали version >= 1.2.0: vars, object, goto.
Следующие модули подключаются автоматически, если вы задали version >= 1.2.0: ''vars'', ''object'', ''goto''.
Объект prefs (находится в модуле prefs) служит для сохранения настроек игры, например, его можно использовать для реализации системы достижений или счетчика количества прохождений…
Объект ''prefs'' (находится в модуле ''prefs'') служит для сохранения настроек игры, например, его можно использовать для реализации системы достижений или счетчика количества прохождений…
<code lua>
require "prefs"
...
@ -1006,19 +1046,21 @@ require "dbg"
end
</code>
Модуль xact позволяет делать ссылки на объекты из других объектов, реакций и life методов в форме {объект:строка} следующим образом:
Модуль ''xact'' позволяет делать ссылки на объекты из других объектов, реакций и ''life'' методов в форме {объект|строка} следующим образом:
<code lua>
...
act = [[ Под столом я заметил {knife:нож}.]]
act = [[ Под столом я заметил {knife|нож}.]]
...
</code>
При этом, объект может быть объектом или именем объекта.
<WRAP center round info>
**Примечание**: до версии 1.2.2 использовался следующий формат ссылок: {объект:строка}.
</WRAP>
**Примечание**: начиная с версии 1.2.2 используется следующий формат ссылок: {объект|строка}.
В этом модуле определены также такие объекты как xact и xdsc.
В этом модуле определены также такие объекты как ''xact'' и ''xdsc''.
xact -- объект - простейшая реакция. Например:
''xact'' -- объект - простейшая реакция. Например:
<code lua>
main = room {
@ -1034,7 +1076,7 @@ main = room {
xact('note1', code [[p "Больше 10 лет."]]);
</code>
xdsc позволяет вставить в список объектов множественное описание:
''xdsc'' позволяет вставить в список объектов множественное описание:
<code lua>
main = room {
forcedsc = true;
@ -1048,7 +1090,7 @@ main = room {
}
}
</code>
Вы можете также использовать комнату xroom:
Вы можете также использовать комнату ''xroom'':
<code lua>
main = xroom {
forcedsc = true;
@ -1060,9 +1102,9 @@ main = xroom {
}
</code>
Модуль input позволяет реализовывать простые поля ввода, а click отслеживает щелчки по картинке сцены.
Модуль ''input'' позволяет реализовывать простые поля ввода, а ''click'' отслеживает щелчки по картинке сцены.
Модуль format выполняет форматирование вывода. По умолчанию все настройки выключены :
Модуль ''format'' выполняет форматирование вывода. По умолчанию все настройки выключены :
<code lua>
format.para = false -- отступы в начале абзаца;
format.dash = false -- замена двойного - на тире;
@ -1070,7 +1112,7 @@ format.quotes = false -- замена " " на << >>;
format.filter = nil -- пользовательская функция замены;
</code>
Вы можете пользоваться модулями para, dash, quotes для включения отдельных настроек.
Вы можете пользоваться модулями ''para'', ''dash'', ''quotes'' для включения отдельных настроек.
==== Форматирование ====
Вы можете делать простое форматирование текста с помощью функций:

View file

@ -1702,8 +1702,6 @@ static void game_pict_clip(void)
y = game_theme.win_y;
w = game_theme.win_w;
h = game_theme.win_h;
if (game_theme.max_scene_h >=0)
h = game_theme.max_scene_h;
} else {
x = game_theme.gfx_x;
y = game_theme.gfx_y;