Some style and visual improvements.

Still need to make labels and table refs.
This commit is contained in:
Alexander Yakovlev 2009-11-10 07:04:03 +00:00
parent 9709aaa919
commit b4125fcbb6
2 changed files with 76 additions and 41 deletions

Binary file not shown.

View file

@ -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. Это некий <<Hello, World>>, который я рекомендую сохранить под именем 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/}{Сайт программы}