diff --git a/doc/manual.pdf b/doc/manual.pdf index e220a6c..a4493f1 100644 Binary files a/doc/manual.pdf and b/doc/manual.pdf differ diff --git a/doc/manual.tex b/doc/manual.tex index dfc285f..3ff3681 100644 --- a/doc/manual.tex +++ b/doc/manual.tex @@ -1,5 +1,5 @@ %На будущее даю инструкции по стилю кода. -%Использовать \verb вместо \texttt +%Использовать \verb вместо \texttt,где это возможно. %Пробелы ДО и ПОСЛЕ таблиц. Только при помощи \medskip. \documentclass[a4paper,12pt]{article} \usepackage[utf8]{inputenc} @@ -7,6 +7,8 @@ \usepackage[a4paper]{geometry} \usepackage[pdftex,colorlinks,linkcolor = blue,urlcolor = blue,unicode]{hyperref} \usepackage{xcolor} +\usepackage{graphicx} +\usepackage{wrapfig}%обтекание текстом \geometry{verbose,tmargin=1cm,bmargin=1cm,lmargin=1cm,rmargin=1cm,headheight=1cm,headsep=1cm,footskip=0.7cm} \usepackage{indentfirst} \begin{document} @@ -15,18 +17,26 @@ \maketitle \tableofcontents \clearpage -\section*{Введение} -Я предполагаю, что вы, читатель, интересуетесь процессом создания игр для движка INSTEAD. Также я думаю, что вы - человек умный и вам не надо повторять дважды. +\section{Введение} +Данный справочник написан в предположении,что читатель знаком с объектно-ориентированным программированием. -Игры для движка STEAD пишутся на языке \href{http://www.lua.org}{Lua} версии 5.1 (то есть, последней на данный момент). Знание этого языка будет очень полезным при написании игр, но я постараюсь сделать описание настолько подробным, что даже новичок в Lua смог программировать без проблем. Между прочим, знающим Lua будет небезынтересно посмотреть код движка. +Игры для движка STEAD пишутся на языке \href{http://www.lua.org}{Lua} версии 5.1 (то есть, последней на данный момент). Знание этого языка будет очень полезным при написании игр, но я постараюсь сделать описание настолько подробным, что даже новичок в этом языке смог создавать игры для INSTEAD без проблем. Между прочим, знающим Lua будет небезынтересно посмотреть код движка. -Главное окно игры содержит информацию о статической и динамической части сцены, активные события и картинку сцены с возможными переходами в другие сцены (в графическом интерпретаторе). +\begin{wrapfigure}{l}{0.55\linewidth} +\includegraphics[scale=0.7]{1.jpg} +\caption{INSTEAD с запущенной игрой} +\label{INSTEAD-running} +\end{wrapfigure} -Динамическая часть сцены составлена из описаний объектов сцены, она отображается всегда. Она может выглядеть так: ``Стоит стол. Рядом стоит стул.''. Если динамическая часть пуста, то игроку не с чем контактировать в сцене. +\textbf{Главное окно} игры содержит информацию о статической и динамической части сцены, активные события и картинку сцены с возможными переходами в другие сцены (в графическом интерпретаторе). -Статическая часть сцены описывает саму сцену, её ``декорации''. Она отображается при показе сцены (единожды или каждый раз -- решает автор игры), или при повторении команды look (в графическом интерпретаторе при щелчке на названии сцены). +\textbf{Динамическая часть} сцены составлена из описаний объектов сцены, она отображается всегда. Она может выглядеть так: <<Стоит стол. Рядом стоит стул>>. Если динамическая часть пуста, то игроку не с чем контактировать в сцене. -Игрок имеет собственный инвентарь. В нём лежат объекты, доступные на любой сцене. Чаще всего инвентарь рассматривают как некую ``котомку'', в которой лежат объекты; в этом случае каждый объект считают предметом. Такая трактовка практична, обыденна и интуитивна; но не единственна. Понятие инвентаря является условным, ведь это лишь контейнер. В нём могут находиться такие объекты, как ``открыть'', ``потрогать'', ``лизнуть''. Можно наполнить его объектами ``нога'', ``рука'', ``мозг''. Автор игры свободен в определении этих понятий, но он также должен определить действия игрока над ними. +\textbf{Статическая часть} сцены описывает саму сцену, её <<декорации>>. Она отображается при показе сцены (единожды или каждый раз -- решает автор игры), или при повторении команды look (в графическом интерпретаторе при щелчке на названии сцены). + +Игрок имеет собственный \textbf{инвентарь}. В нём лежат объекты, доступные на любой сцене. Чаще всего инвентарь рассматривают как некую <<котомку>>, в которой лежат объекты; в этом случае каждый объект считают предметом. Такая трактовка практична, обыденна и интуитивна; но не единственна. Понятие инвентаря является условным, ведь это лишь контейнер. В нём могут находиться такие объекты, как <<открыть>>, <<потрогать>>, <<лизнуть>>. Можно наполнить его объектами <<нога>>, <<рука>>, <<мозг>>. Автор игры свободен в определении этих понятий, но он также должен определить действия игрока над ними. + +На рисунке \ref{INSTEAD-running} очень чётко видны границы между этими областями. Главное окно имеет бежевый фон\footnote{Поправьте меня,если я неправ; в описании главного окна нет инвентаря}, инвентарь - чёрный.Динамическая часть идёт сразу после ссылок перехода и выделена курсивом; статическая часть отпечатана обычным шрифтом. Действиями игрока могут быть: @@ -40,34 +50,31 @@ Осмотр сцены - это чаще всего неявное действие. Игрок входит в комнату, он автоматически осматривает её. -Действие на объект сцены обычно понимается как изучение объекта, или использование его. Например, если в сцене существует объект ``чашка кофе'', то действием на него может быть выпивание кофе, тщательный осмотр чашки, разбивание чашки или перемещение чашки в инвентарь. Это определяется только автором и никем другим. +Действие на объект сцены обычно понимается как изучение объекта, или использование его. Например, если в сцене существует объект <<чашка кофе>>, то действием на него может быть выпивание кофе, тщательный осмотр чашки, разбивание чашки или перемещение чашки в инвентарь. Это определяется только автором и никем другим. -Действие на объект инвентаря понимается аналогично. Например, если в инвентаре лежит объект ``яблоко'', его можно съесть или осмотреть. С другой стороны, если в инвентаре лежит объект ``осмотреть'', то действие над ним будет трудно описать логически. +Действие на объект инвентаря понимается аналогично. Например, если в инвентаре лежит объект <<яблоко>>, его можно съесть или осмотреть. С другой стороны, если в инвентаре лежит объект <<осмотреть>>, то действие над ним будет трудно описать логически. -Действие объектом инвентаря на объект сцены -- это чаще всего использование или передача объекта. Например, действие объектом ``нож'' на объект ``бармен'' может означать передачу ножа бармену, угрозу ножом бармену, убийство ножом бармена и многое другое. +Действие объектом инвентаря на объект сцены -- это чаще всего использование или передача объекта. Например, действие объектом <<нож>> на объект <<бармен>> может означать передачу ножа бармену, угрозу ножом бармену, убийство ножом бармена и многое другое. -Действие объектом инвентаря на объект инвентаря понимается так же свободно. Это может быть соединение предметов (``сарделька'' + ``кетчуп'') в одно (``сарделька с кетчупом''), либо использование (``открыть'' + ``ящик''). +Действие объектом инвентаря на объект инвентаря понимается так же свободно. Это может быть соединение предметов (<<сарделька>> + <<кетчуп>>) в одно (<<сарделька с кетчупом>>), либо использование (<<открыть>> + <<ящик>>). Эти примеры подробно показывают первую из идей STEAD - гибкость. Автор свободен в своей фантазии и может трактовать все понятия движка как хочет. Игра представляет из себя каталог, в котором должен находиться скрипт main.lua. Другие ресурсы игры (скрипты на lua, графика и музыка) должны находиться в рамках этого каталога. Все ссылки на ресурсы делаются относительно текущего каталога -- каталога игры. -Игра начинается именно с main.lua. В начале файла main.lua может быть определён заголовок, состоящий из тегов. Теги должны начинаться с символов комментария \verb/--/. На данный момент существует один тег: \verb/$Name:/, который должен содержать название игры. Пример использования тега: +Игра начинается именно с main.lua. В начале файла main.lua может быть определён заголовок, состоящий из тегов. Теги должны начинаться с символов комментария \verb/--/. На данный момент существует один тег: \verb/$Name:,/ который должен содержать название игры. Пример использования тега: \begin{verbatim} -- $Name: Самая интересная игра!$ \end{verbatim} -Интерпретатор ищет доступные игры в каталогах:\\ -Unix версия интерпретатора просматривает игры в каталогах:\\ -\verb;/usr/local/share/instead/games; (по умолчанию),\\ -\verb,~/.instead/games,.\\ -WinXP версия:\\ -\verb;Documents and Settings/USER/Local Settings/Application Data/instead/games;\\ -WinVista: \verb;Users\USER\AppData\Local\instead\games;\\ -Все Windows: \verb;куда-вы-установили-INSTEAD/games; +Интерпретатор ищет доступные игры в следующих каталогах: -В дальнейшем я буду отталкиваться от возможностей графической ветки интерпретатора -- \\ INSTEAD-SDL. +Unix версия интерпретатора просматривает \verb;/usr/local/share/instead/games; (по умолчанию), а также \verb,~/.instead/games,. + +Windows сборка использует каталог \verb/куда-вы-установили-INSTEAD\games/; каталоги пользовательских игр немного меняются в зависимости от вашей версии Windows. В Windows XP это \texttt{Documents and Settings/USER/Local Settings/Application Data/instead/games}, когда как в Windows Vista это \verb;Users\USER\AppData\Local\instead\games;. + +На данный момент активно развивается только графическая ветка интерпретатора -- INSTEAD-SDL. Поэтому справочник в б\'{о}льшей мере описывает её возможности. \section{Сцена} @@ -80,7 +87,7 @@ main = room { }; \end{verbatim} -Отмечу, что пример выше является минимальной игрой для INSTEAD. Это некий ``Hello, World'', который я рекомендую сохранить под именем main.lua и поместить в отдельную папку в каталоге для игр. +Отмечу, что пример выше является минимальной игрой для INSTEAD. Это некий <>, который я рекомендую сохранить под именем main.lua и поместить в отдельную папку в каталоге для игр. Атрибут \verb/nam/ (имя) является необходимым для любого объекта. Для сцены это -- то, что будет заголовком сцены при её отображении. Имя сцены также используется для её идентификации при переходах. @@ -130,7 +137,7 @@ table = obj { \verb/act/ -- это обработчик, который вызывается при действии пользователя на объект сцены. Если объект находится в инвентаре, то действие с ним будет передаваться другому обработчику -- \verb/inv/. -Настало время сделать небольшое отступление. До сих пор в примерах приводились примитивные обработчики, которые всего лишь возвращают определённую строку. В примере выше обращение к объекту вызовет банальную реакцию: интерпретатор напечатает строку ``Гм... Просто стол...''. Хуже того: он будет отвечать тем же образом каждый раз при обращении к объекту. Это не совсем гибкий подход, поэтому STEAD позволяет определить любой атрибут объекта как функцию. Так, возможно построить такую конструкцию: +Настало время сделать небольшое отступление. До сих пор в примерах приводились примитивные обработчики, которые всего лишь возвращают определённую строку. В примере выше обращение к объекту вызовет банальную реакцию: интерпретатор напечатает строку <<Гм... Просто стол...>>. Хуже того: он будет отвечать тем же образом каждый раз при обращении к объекту. Это не совсем гибкий подход, поэтому STEAD позволяет определить любой атрибут объекта как функцию. Так, возможно построить такую конструкцию: \begin{verbatim} apple = obj { @@ -153,7 +160,9 @@ apple = obj { }; \end{verbatim} -Если атрибут или обработчик оформлен как функция, то обычно первый аргумент функции (s) сам объект. В данном примере, при показе сцены будет в динамической части сцены будет текст: ``На столе что-то лежит''. При взаимодействии с ``что-то'', переменная \verb/_seen/ объекта \verb/apple/ будет установлена в \verb/true/, и мы увидим, что это было яблоко. +Если атрибут или обработчик оформлен как функция, то обычно первый аргумент функции \verb/(s)/ есть сам объект. В данном примере, при показе сцены будет в динамической части сцены будет текст: <<На столе что-то лежит>>. При взаимодействии с <<что-то>>, переменная \verb/_seen/ объекта \verb/apple/ будет установлена в \verb/true/, и мы увидим, что это было яблоко. + +Если аргумент у функции единственен, то скобки вокруг аргумента можно опускать. Так, например, \verb/return/ -- это функция, но здесь она написана без скобок. Дальнейшие примеры будут часто использовать эту возможность. Вы можете и не опускать скобки, если это не нравится вам по стилю. Запись \verb/s._seen/ означает, что переменная \verb/_seen/ размещена в объекте \verb/s/ (то есть, \verb/apple/). В языке Lua переменные необязательно объявлять заранее, при первом обращении к ней переменная \verb/apple._seen/ появится сама; но хорошим тоном будет заранее \textbf{проинициализировать} переменную со значением \verb/false/. @@ -181,9 +190,9 @@ sside = room { Как видим, \verb/vobj/ позволяет сделать лёгкую версию статического объекта, с которым тем не менее можно взаимодействовать (за счёт определения обработчика \verb/act/ в сцене и анализа ключа объекта). \verb/vobj/ также вызывает метод \verb/used/, при этом в качестве третьего параметра передаётся объект, воздействующий на виртуальный объект. -Синтаксис \verb/vobj/: \verb/vobj(ключ, имя, описатель);/ где ключ -- это цифра, которая будет передана обработчикам \verb.act/used. сцены как второй параметр. +Синтаксис \verb/vobj/ таков: \verb/vobj(ключ, имя, описатель);,/ где ключ -- это цифра, которая будет передана обработчикам \verb.act/used. сцены как второй параметр. -Существует модификация объекта \verb/vobj/ -- \verb/vway/. \verb/vway/ реализует ссылку. Синтаксис и пример: +Существует модификация объекта \verb/vobj/ под именем \verb/vway/. \verb/vway/ реализует ссылку. Синтаксис и пример: \begin{verbatim} vway(имя, описание, сцена назначения); @@ -222,7 +231,7 @@ put(new [[obj {nam = 'test' } ]]); put(new('myconstructor()'); \end{verbatim} -Созданный объект будет попадать в файл сохранения. \verb/new()/ возвращает реальный объект;чтобы получить его имя,если это нужно, используйте функцию\verb/deref/. +Созданный объект будет попадать в файл сохранения. \verb/new()/ возвращает реальный объект; чтобы получить его имя,если это нужно, используйте функцию \verb/deref()./ \section{Некоторые манипуляции с объектами} @@ -242,7 +251,7 @@ main = room { \subsection{Объекты, связанные с объектами} -Объекты тоже могут содержать атрибут \verb/obj/. При этом, список будет последовательно разворачиваться. Например, поместим на стол яблоко: +Объекты тоже могут содержать атрибут \verb/obj./ При этом, список будет последовательно разворачиваться. Например, поместим на стол яблоко: \begin{verbatim} apple = obj { @@ -257,7 +266,7 @@ table = obj { }; \end{verbatim} -При этом, в описании сцены мы увидим описание объектов ``стол'' и ``яблоко'', так как \verb/apple/ -- связанный с \verb/table/ объект. +При этом, в описании сцены мы увидим описание объектов <<стол>> и <<яблоко>>, так как \verb/apple/ -- связанный с \verb/table/ объект. \subsection{Действия объектов друг на друга} @@ -295,6 +304,17 @@ return 'Строка реакции', false; Возможно также действовать объектами сцены на объекты сцены; для этого нужно установить переменную \verb/game.scene_use = true/ или поставить \verb/scene.use=true/ в нужной комнате. В этом случае использование объектов сцены будет аналогично использованию объектов инвентаря. +\subsection{Скрытие объектов} + +При помощи методов \verb/enable/ и \verb/disable/ становится возможным управлять появлением и исчезновением объектов. + +Скрытый объект -- это объект, который находится в сцене, но на данный момент словно бы ,,выключен``. Он присутствует для движка, но не существует для игрока. Его описание не выводится и с ним невозможно контактировать. Это можно использовать, например, вместо динамического создания объектов. + +Чтобы создать заведомо выключенный объект, необходимо воспользоваться конструкцией вида \verb/knife = {<...>}:disable()./ +Объект \verb/knife/ будет создан и тут же выключен. + +Методы \verb/enable()/ и \verb/disable()/ возвращают сам объект. Они присутствуют у любого объекта и списка объектов. + \section{Смена сцен} Как только главный герой уходит со сцены, декорации меняются. Но чтобы игрок ушёл из нашей сцены, он должен знать, куда идти. @@ -384,6 +404,17 @@ apple = obj { Атрибут \verb/obj/ представляет собой инвентарь игрока. +Объекты игрока можно воспринимать как объекты инвентаря, в этом случае верны следующие конструкции: + +\begin{verbatim} +remove('knife', me()); +put('knife', me()); +take('knife', me()); +where('knife'); +\end{verbatim} + +Необходимо отметить, что это верно не в каждой игре. + \subsection{Игра} Игра представлена объектом \verb/game/. Он хранит в себе указатель на текущего игрока (\verb/'pl'/) и некоторые параметры. Например, вы можете указать в начале своей игры кодировку текста следующим образом: @@ -437,7 +468,7 @@ povardlg = dlg { \verb/phr/ -- создание фразы. Фраза содержит вопрос, ответ и реакцию (реакция в данном примере отсутствует). Когда игрок выбирает одну из фраз, фраза отключается. Когда все фразы отключатся диалог заканчивается. Реакция -- это строка кода на lua который выполнится после отключения фразы. -\verb/_phr/ -- создание выключенной фразы. Она не видна изначально, но её можно включить с помощью функции \verb/pon()/ (см. ниже). +\verb/_phr/ -- создание выключенной фразы. Она не видна изначально, но её можно включить с помощью функции \verb/pon()/ (см. ниже). По смыслу это эквивалентно \verb/phr(<...>):disable()./ Вот как создаётся фраза: @@ -602,7 +633,7 @@ mycat = obj { end, \end{verbatim} -В этом примере кот по имени Барсик, сидя в инвентаре у игрока, будет на каждом шагу показывать свою активность. Но приведённый код пока что не будет работать. Для того,чтобы объявить объект ``живым'', следует добавить его в соответствующий список с помощью функции \verb/lifeon()/. +В этом примере кот по имени Барсик, сидя в инвентаре у игрока, будет на каждом шагу показывать свою активность. Но приведённый код пока что не будет работать. Для того,чтобы объявить объект <<живым>>, следует добавить его в соответствующий список с помощью функции \verb/lifeon()/. \begin{verbatim} inv():add('mycat'); @@ -613,7 +644,7 @@ mycat = obj { Вы можете вернуть из обработчика life второй код возврата, важность. (true или false). Если он равен true, то возвращаемое значение будет выведено ДО описания объектов; по умолчанию значение равно false. -Если вы хотите ``очистить экран'', то можно воспользоваться вот каким хаком. Из метода \verb/life/ доступна переменная \verb/ACTION_TEXT/ -- это тот текст, который содержит реакцию на действие игрока. Соответственно, сделав \verb/ACTION_TEXT = nil/,можно ``запретить'' вывод реакции. Например,для перехода на конец игры можно сделать: +Если вы хотите <<очистить экран>>, то можно воспользоваться вот каким хаком. Из метода \verb/life/ доступна переменная \verb/ACTION_TEXT/ -- это тот текст, который содержит реакцию на действие игрока. Соответственно, сделав \verb/ACTION_TEXT = nil/,можно <<запретить>> вывод реакции. Например,для перехода на конец игры можно сделать: \begin{verbatim} ACTION_TEXT = nil @@ -832,9 +863,10 @@ iface:shell(); \hline } +\begin{table}[p] \begin{tabular}{|l|c|l|c|l|c|l|c} \hline -параметр & & параметр & & параметр & \\ +параметр & & параметр & & параметр & & параметр & \\ \hline \tabsParam{aliceblue}{\colorbox[HTML]{F0F8FF}{T.}}{forestgreen}{\colorbox[HTML]{228B22}{T.}}{mediumvioletred}{\colorbox[HTML]{C71585}{T.}}{violet}{\colorbox[HTML]{EE82EE}{T.}} \tabsParam{antiquewhite}{\colorbox[HTML]{FAEBD7}{T.}}{fuchsia}{\colorbox[HTML]{FF00FF}{T.}}{midnightblue}{\colorbox[HTML]{191970}{T.}}{violetred}{\colorbox[HTML]{D02090}{T.}} @@ -881,10 +913,8 @@ iface:shell(); \tabParam{feldspar}{\colorbox[HTML]{D19275}{T.}}{mediumslateblue}{\colorbox[HTML]{7B68EE}{T.}}{thistle}{\colorbox[HTML]{D8BFD8}{T.}} \tabParam{firebrick}{\colorbox[HTML]{B22222}{T.}}{mediumspringgreen}{\colorbox[HTML]{00FA9A}{T.}}{tomato}{\colorbox[HTML]{FF6347}{T.}} \tabParam{floralwhite}{\colorbox[HTML]{FFFAF0}{T.}}{mediumturquoise}{\colorbox[HTML]{48D1CC}{T.}}{turquoise}{\colorbox[HTML]{40E0D0}{T.}} -%ЗДЕСЬ КОНЧАЕТСЯ СТРАНИЦА \end{tabular} - -\newpage +\end{table} \subsection{Параметры окна изображений} @@ -898,7 +928,7 @@ iface:shell(); \texttt{#1} & #2 & #3 \\ \hline } - +\begin{table}[h] \begin{tabular}{|l|c|l|} \hline параметр & тип & описание \\ @@ -920,6 +950,7 @@ iface:shell(); \tabParam{win.gfx.h}{число}{синоним \texttt{scr.gfx.h}} \tabParam{scr.gfx.mode}{строка}{режим расположения} \end{tabular} +\end{table} \medskip @@ -938,6 +969,7 @@ iface:shell(); \medskip +\begin{table}[h] \begin{tabular}{|l|c|l|} \hline параметр & тип & описание \\ @@ -955,17 +987,17 @@ iface:shell(); \tabParam{win.col.link}{цвет}{цвет ссылок главного окна} \tabParam{win.col.alink}{цвет}{цвет активных ссылок главного окна} \end{tabular} +\end{table} \medskip -\clearpage - \subsection{Параметры области инвентаря} Для области инвентаря заданы следующие параметры: \medskip +\begin{table}[h] \begin{tabular}{|l|c|l|} \hline параметр & тип & описание \\ @@ -983,6 +1015,7 @@ iface:shell(); \tabParam{inv.gfx.down}{строка}{путь к изображению скроллера вниз для инвентаря} \tabParam{inv.mode}{строка}{режим инвентаря} \end{tabular} +\end{table} \medskip @@ -996,6 +1029,7 @@ iface:shell(); \medskip +\begin{table}[h] \begin{tabular}{|l|c|l|} \hline параметр & тип & описание \\ @@ -1015,6 +1049,7 @@ iface:shell(); \tabParam{snd.click}{строка}{путь к звуку щелчка} \tabParam{include}{строка}{имя темы} \end{tabular} +\end{table} \medskip @@ -1045,7 +1080,7 @@ WinVista: \verb;Users\USER\AppData\Local\instead\themes;\\ Игра может задавать собственную тему; для этого в каталоге с игрой должен лежать тот самый \verb/theme.ini/. Его формат никак при этом не меняется, просто он загружается в первую очередь вместе с игрой. \section{Дополнительные источники документации} -Вот и закончен справочник по INSTEAD. Напомним, что INSTEAD расшифровывается (и переводится) как ``Интерпретатор простых текстовых приключений''. Официальная документация находится в каталоге doc и поставляется с instead. Дополнительную информацию вы можете получить в Интернете: +Вот и закончен справочник по INSTEAD. Напомним, что INSTEAD расшифровывается (и переводится) как <<Интерпретатор простых текстовых приключений>>. Официальная документация находится в каталоге doc и поставляется с instead. Дополнительную информацию вы можете получить в Интернете: \begin{itemize} \item \href{http://instead.googlecode.com/}{Сайт программы}