Инструменты пользователя

Инструменты сайта


help:principle

Различия

Здесь показаны различия между двумя версиями данной страницы.

Ссылка на это сравнение

Both sides previous revision Предыдущая версия
Следущая версия
Предыдущая версия
help:principle [2013/11/02 13:41]
newsash [Порядок работы интерпретатора]
help:principle [2024/10/14 07:28] (текущий)
aleks_versus проба обновления до 5.9.0
Строка 1: Строка 1:
-[[help:jump|Назад:​ Переходы внутри локации,​ циклы]] +[[help:objs|Назад:​ Предметы]]
-=====Порядок работы интерпретатора=====+
  
-При обработке новой локации (напримерпри переходе с помощью операторов "GOTO, XGOTO, GOSUB"выполняются следующие действия:​ +====== ​Порядок работы ​интерпретатора ====== 
-  ​- Очистка списка ​действий предыдущей локации, если был осуществлен непосредственный переход на локацию ​(например,​ с помощью операторов "GOTOXGOTO"); + 
-  - Обновление поля описания локации ​амена существующего основного описания,​ либо добавление к нему текста ​базового описания новой локации ​в зависимости от тогокаким образом был произведён переход); +**Несмотря на то, что эта статья ​обросла некоторыми подробностями, она всё ещё требует серьёзной редактуры, упрощения и расширения. Так что пока что это всё ещё черновой ​вариант.** 
-  ​- Добавление базовых действий новой локации; + 
-  - Последовательное выполнение операторов, находящихся в поле "​Выполнить при посещении"​; +Эта статья подробно рассказывает о порядке работы интерпретатора (плеера) **QSP**. Она может показаться вам довольно сложной,​ но читать её всю не обязательно. Вернитесь к ней, когда у вас возникнут сложности в понимании того, как ведёт себя плеер. А пока достаточно ознакомиться с общими принципами:​ 
-  ​- При непосредственном переходе на локацию ​выполняется ​обработка локации-обработчика ​перехода на новую локацию,​ если таковая указана; + 
-  ​- ​Если переменная локации-счётчика не пуста, то происходит обработка соответствующей локации (по умолчанию2 раза в секунду); +  * При запуске игры автоматически воспроизводится только самая первая в игре локация. На остальные локации нужно осуществлять ​переходы с помощью ​**''​GOTO''​** или **''​XGOTO''​**,​ или вызывать их с помощью **''​GOSUB''​**,​ **''​FUNC''​**,​ или иным ​предусмотренным плеером способом. 
-  ​- Обновление интерфейса (шрифт, цвета, ​заданные с помощью системных переменных) - также, по умолчаниюраза в секунду; +  * Код действий "прикрепляется" ​к действию и не выполняется,​ пока игрок не нажмёт на действие. 
-  ​- ​При выборе действия или предмета пользователем, происходит обработка локаций-обработчиков выбора действий и предметов+  * Все команды ​выполняются ​последовательно одна за другой, ​и никогда не выполняются одновременно. 
-  - При загрузке или сохранении состояния игры, происходит обработка локаций-обработчиков загрузки и сохранения игры; + 
-  ​- Если пользователь ​щёлкает на действии,​ то выполняются операторы,​ определённые для этого действия+Ниже по тексту будут использоваться следующие определения: 
-  ​Если пользователь нажимает ​"​Enter" ​в строке ввода, то происходит обработка локации-обработчика строки ввода.+ 
 +  ​* **Переход на локацию** — это ​событие в игре, ​которое происходит при обращении к локации ​с помощью операторов **''​GOTO''​** ​или **''​XGOTO''​**. При этом локация ​становится "активной",​ или "​текущей"​. Функция **''​$CURLOC''​** возвращает название локации,​ на которую был совершён переход,​ а массив **''​ARGS[]''​** этой локации ​сохраняет свои значения, ​пока снова не будет осуществлён переход на локацию (другую, или ту же самую). После добавления текста из поля "​Базовое описание"​ в Окно основного описания,​ действий из поля "​**Базовые действия**"​ в **Окно действий**,​ и выполнения кода из поля "​**Выполнить при посещении**"​плеер "останавливается"​ и ожидает участия игрока,​ при этом локация,​ на которую ​был осуществлён переход, остаётся "​активной" ("​текущей"​),​ т.е. функция **''​$CURLOC''​** в любой момент может вернуть название этой локации,​ а массив ''​ARGS[]''​ сохраняет значения.\\ Для переходов существуют только два оператора (подробнее см. статью [[help:​goto|"​Переходы"​]]):​ 
 +    * **''​GOTO''​** — осуществляет ​переход на указанную ​локацию ​с автоматической очисткой **Окна основного описания** и **Окна действий**. 
 +    * **''​XGOTO''​** — осуществляет переход на указанную локацию с автоматической очисткой **Окна действий**. **Окно основного описания** НЕ очищается. 
 +  * **Вызов локации** — это событие в игрекоторое происходит при обращении к локации ​с помощью оператора **''​GOSUB''​**,​ функции **''​FUNC''​**,​ или ​в связи с выполнением другого события (например,​ "​**Выделение предмета**", "**Загрузка сохранения**",​ "​**Ввод в поле ввода**",​ "​**Выбор пункта меню**"​). В отличие от **перехода на локацию**, ​при **вызове** локация не становится "​активной"​ ("​текущей"​),​ т.е. функция **''​$CURLOC''​** не возвращает название этой ​локацииа массив **''​ARGS[]''​** сохраняет свои значения ​только пока ​выполняется код локации. После выполнения кода локации,​ продолжается ​выполнение того ​блока кода, который выполнялся до вызова. Например, если локация была **вызвана** из действия, то после выполнения её кода, продолжится ​выполнение кода действия,​ при этом в массив **''​ARGS[]''​** внутри действия не попадут значения массива **''​ARGS[]''​** из вызванной локации. При ​вызове локации в **Окно основного описания** добавляется текст из поля "​**Базовое описание**"​ локации, ​в **Окно действий** добавляются действия из поля "​**Базовые действия**" ​локации, и выполняется код из поля "​**Выполнить при посещении**"​ локации. Очистка окон при ​вызове локации НЕ ПРОИСХОДИТ. <sxh qsp> 
 +act "​Действие с вызовом локации":​ 
 +  *pl "​Выводим текст до вызова"​ 
 +  gosub '​foo'​ & ! вызываем локацию foo 
 +  *pl "Продолжаем выполнять код после вызова локации foo" 
 +end 
 +</​sxh>​ Вызвать локацию можно ​разными способами: 
 +    * Оператор **''​GOSUB''​** вызывает ​локацию без возвращения результата (подробнее в статье [[help:​organizing|"​Пользовательские функции и процедуры"​]]). 
 +    * Оператор **FUNC** вызывает локацию с возвращением результата (подробнее в статье [[help:​organizing|"​Пользовательские функции и процедуры"​]]). 
 +    * Нажатием пункта всплывающего меню (см. статью [[help:​menu|"​Всплывающее меню"​]]) 
 +    * Выполнением какого-либо события в игре, как то: "​Выделение предмета",​ "​Выделение действия",​ "​Загрузка сохранения",​ "Ввод текста в поле ввода"​ и т.д. (подробнее в статье [[help:​service_locations|"​Служебные локации"​]]). 
 +  ​* **Блок кода** — это ​выделенный в отдельное целое фрагмент кода ​игры. Отдельными ​блоками кода в **QSP** являются:​ 
 +    * Локации сами со себе. 
 +    * Код, передаваемый оператору **''​DYNAMIC''​** или функции **''​DYNEVAL''​** в виде текста. 
 +    * Код, ​выполняемый при нажатии на гиперссылку. 
 +    * Код каждого отдельного Действия (**[[help:​acts|ACT]]**). 
 +    * Код каждого отдельного Цикла (**[[help:​cycle|LOOP]]**) 
 + 
 +===== Запуск игры ===== 
 + 
 +Каждая игра на **QSP** структурно представляет собой набор ​локаций, последовательно ​записанных ​в файл. 
 + 
 +Когда мы открываем игру в плеере (интерпретаторе),​ автоматически запускается чтение ​самой первой локации в файле (далее **Стартовая локация**)как если бы на неё был совершён переход ​с помощью оператора **''​GOTO''​**. То есть: 
 + 
 +  * В Окно основного описания добавляется текст из поля "​**Базовое описание**"​ локации (поле "​**Описание**"​ в **Quest Generator**). 
 +  * В Окно действий добавляются действия из поля "​**Базовые действия**"​ локации (поле "​**Базовые действия**"​ в **Quest Generator**). 
 +  * Выполняется код из поля ​"**Выполнить при посещении**" ​локации. 
 +  ​* Если на Стартовой локации в переменную **''​$ONNEWLOC''​** было помещено название локации-обработчика события "**Переход на новую ​локацию**", ​произойдёт ​автоматический вызов этой самой ​локации-обработчика ​события "**Переход на новую локацию**" (см. [[help:​service_locations|"​Служебные локации"​]]). 
 +  * После тогокак Стартовая локация была прочитана,​ плеер "останавливается" и ожидает действий от игрока. При этом локация остаётся "​активной",​ т.е. функция **''​$CURLOC''​** в любой момент может вернуть её название, а в массиве **''​ARGS[]''​** данной локации сохраняются значения,​ которые на ней были выставлены,​ и эти значения могут использоваться,​ например,​ в действиях,​ выведенных в **Окно действий**. 
 + 
 +Если ​на Стартовой локации в переменную **''​$COUNTER''​** было помещено ​название ​локации-счётчика, примерно через равные промежутки времени (по умолчанию раз в пол ​секунды) плеер будет вызывать локацию-счётчик (см. [[help:​service_locations|"​Служебные локации"​]]). 
 + 
 +===== Выполнение кода ===== 
 + 
 +Код в **QSP** всегда выполняется последовательнокоманда за командой. Чтение команд ​происходит ​сверху вниз и справа налево
 + 
 +<sxh qsp> 
 +*pl "Первая команда"​ 
 +*pl "Вторая ​команда"​ 
 +*pl "​Третья команда"​ 
 + 
 +*pl "​Четвёртая команда"​ & *pl "​Пятая команда"​ & *pl "Шестая команда"​ 
 +</​sxh>​ 
 + 
 +**QSP** не способен выполнить две команды одновременно,​ или ​случайно выполнить вторую команду раньше первой. Поэтому в большинстве случаев,​ если вам кажется,​ что плеер "​забывает"​ выполнить ​какую-либо команду,​ скорее всего эта команда написана в таком месте, где ​плеер просто не может до неё добраться. 
 + 
 +Например,​ если написано невыполнимое ​условие,​ команда никогда не будет выполнена: 
 + 
 +<sxh qsp> 
 +if 5>6: 
 +  *pl "​Данная команда никогда не будет выполнена"​ 
 +end 
 +</​sxh>​ 
 + 
 +Командыстоящие после **''​GOTO''​** или **''​XGOTO''​**,​ так же никогда не будут ​выполнены:​ 
 + 
 +<sxh qsp> 
 +*pl "​Текст на локации"​ & ! этот текст будет виден на локации всегда 
 +act "​Переход по XGOTO":​ 
 +  *pl "​Этот текст виден благодаря тому, что вы перешли с помощью XGOTO" 
 +  ​xgoto $curloc & ! переходим на текущую локацию 
 +  *pl "А эта команда никогда не будет выполнена"​ 
 +end 
 + 
 +act "​Переход по GOTO":​ 
 +  *pl "​Эта команда будет ​выполнена" 
 +  ! но при переходе по GOTO Окно основного описания очистится, 
 +  ! так что эту строчку вы всё равно не увидите. 
 +  goto $curloc & ! переходим на текущую локацию 
 +  *pl "А эта команда никогда не будет выполнена"​ 
 +end 
 +</​sxh>​ 
 + 
 +Код действий ​(**''​ACT''​**) не выполняется сразу, а "прикрепляется"​ к этим действиям. Он будет выполнен только тогда, когда игрок нажмёт на соответствующее ​действие. 
 + 
 +<sxh qsp> 
 +example=12 & ! присваиваем переменной число 12 
 +! создаём действие 
 +act "Вывести значение ​переменной example":​ 
 +  *pl example 
 +end 
 +example=37 & ! меняем значение в переменной 
 +</​sxh>​ 
 + 
 +То же самое происходит с кодом в гиперссылках. Он не выполняется сразу, когда мы создаём гиперссылку,​ он выполняется только тогда, когда мы на гиперссылку нажимаем:​ 
 + 
 +<sxh qsp> 
 +usehtml=1 & ! включаем режим распознавание HTML 
 +example=12 
 +! выводим на экран гиперссылку с кодом 
 +*pl "<a href='​EXEC:​*pl example'>​Вывести значение переменной example</​a>"​ 
 +example=37 
 +</​sxh>​ 
 + 
 +При выполнении команды,​ которая содержит строки с вложенными выражениями, сначала раскрываются вложенные выражения,​ и только затем происходит работа со строкой, например, передача её оператору для вывода на экран:​ 
 + 
 +<sxh qsp> 
 +яблоки = 23 
 +! Сначала в строку подставится значение, 
 +! потом строка выведется на экран
 +*pl "​Яблок в кармане:​ <<​яблоки>>​."​ 
 +</​sxh>​ 
 + 
 +===== Переход на новую локацию ===== 
 + 
 +Переход на новую локацию может осуществляться с помощью двух операторов **''​GOTO''​** и **''​XGOTO''​**. Различие в их работе заключается в следующем:​ 
 + 
 +  * При переходе с помощью оператора **''​GOTO''​** очищаются Окно основного описания и Окно действий. 
 +  * При переходе с помощью оператора **''​XGOTO''​** очищается только Окно действий. Окно основного описания не очищается. 
 + 
 +В остальном работа этих операторов схожа:​ 
 + 
 +  * В Окно основного описания добавляется текст из поля "Базовое описание"​ локации (поле "​Описание"​ в **Quest Generator**). 
 +  * В Окно действий добавляются действия из поля "​Базовые действия"​ локации (поле "​Базовые действия" в **Quest Generator**). 
 +  * Выполняется код из поля "​Выполнить при посещении"​ локации. 
 +  * Если в переменную **''​$ONNEWLOC''​** было помещено название локации-обработчика события "​Переход на новую ​локацию", произойдёт автоматический вызов этой самой локации-обработчика события "​Переход на новую локацию"​ (см. [[help:​service_locations|"​Служебные локации"​]]). 
 +  * После этого плеер "​останавливается"​ и ожидает ​действий ​от игрока. При этом локация остаётся "​активной",​ т.е. функция **''​$CURLOC''​** в любой момент может ​вернуть её название, а в массиве **''​ARGS[]''​** данной локации сохраняются ​значения, которые на ней были выставлены,​ и эти значения могут использоваться,​ например,​ в действиях,​ выведенных в **Окно действий**. 
 + 
 +Если в переменную **''​$COUNTER''​** было помещено название локации-счётчика,​ примерно через ​равные промежутки времени ​(по умолчанию раз в пол ​секунды) плеер будет вызывать локацию-счётчик (см. [[help:​service_locations|"​Служебные локации"​]]). 
 + 
 +P.S.: "​Переход на новую локацию"​ — это устоявшееся название события. Технически более правильно называть такие переходы просто "​Переход на локацию"​, поскольку мы можем переходить не только на новые, но и на текущую локацию:​ 
 + 
 +<sxh qsp> 
 +"​Счёт:​ <<​count>>"​ 
 +act "​Обновить":​ 
 +  count+=1 
 +  goto $curloc & ! перезаходим на текущую локацию 
 +end 
 +</​sxh>​ 
 + 
 +Поэтому, ​столкнувшись с выражением "​Переход ​на новую локацию" помните,​ что оно может значить в том числе и переход на текущую локацию. 
 + 
 +===== Вызов локации ===== 
 + 
 +Вызов локации может ​быть выполнен напрямую через оператор [[help:​organizing|**GOSUB**]] или функцию [[help:​organizing|**FUNC**]] или в привязке к какому-либо [[help:​service_locations|событию]]. 
 + 
 +При вызове:​ 
 + 
 +  * В Окно основного описания добавляется текст из поля "​Базовое описание" ​локации (поле "​Описание"​ в **Quest Generator**). 
 +  * В Окно действий добавляются действия из поля "​Базовые действия"​ локации (поле "​Базовые действия"​ в **Quest Generator**). 
 +  * Выполняется код из поля "​Выполнить при посещении"​ локации. 
 + 
 +Дополнительно, при вызове с помощью оператора **''​GOSUB''​**,​ или функции **''​FUNC''​**,​ а так же с помощью оператора [[help:​menu|**MENU**]],​ осуществляется возврат к тому коду, из которого был осуществлён вызов, и продолжается выполнение этого ​кода. Например, если локация была вызвана из действия, то произойдёт возврат к выполнению кода действия
 + 
 +<sxh qsp> 
 +act "​Действие с вызовом локации":​ 
 +  ​*pl "​Выводим текст до вызова"​ 
 +  gosub '​foo'​ & ! вызываем ​локацию foo 
 +  *pl "​Продолжаем выполнять код после вызова ​локации foo" 
 +end 
 +</​sxh>​ 
 + 
 +Более подробно работа оператора **''​GOSUB''​** и функции **''​FUNC''​** освещена в разделе [[help:​organizing|"​Пользовтальские функции и процедуры"​]]. 
 + 
 +О работе оператора **''​MENU''​** более подробно можно почитать в разделе [[help:​menu|"​Меню"​]]. 
 + 
 +===== Обработка событий ===== 
 + 
 +События,​ если смотреть на это понятие с точки зрения работы плеера,​ — это некое изменение состояния ​в написанной нами игре. Напримеру нас все предметы были не выделены,​ и вот игрок щёлкает мышью по одному из предметов, и предмет оказывается выделен. То есть ​предмет изменил своё состояние с "не выделен", на "​выделен"​. Это и есть **событие выделения предмета**. 
 + 
 +Конечно,​ мы могли бы и сами отслеживать некоторые события,​ например,​ с помощью локации-счётчика постоянно проверять, какое значение возвращает нам функция **''​$SELOBJ''​**,​ и в момент, когда функция изменяет своё значение с одного на другое, мы точно знаемчто произошло выделение нового предмета, или иными словами:​ событие "​Выделение предмета"​. Однако,​ для нас это, во-первых,​ лишний код, а, во-вторых,​ очень неудобный и неточный инструмент по отслеживанию событий,​ поскольку локация-счётчик имеет ряд ограничений и на скорость выполнения, и на очерёдность. Мы хотим, чтобы миллисекунда в миллисекунду мы знали, что какое-то событие произошло,​ и чтобы при этом мы могли выполнить какой-либо код. 
 + 
 +Именно ​для этого ​в **QSP** введены специальные служебные локации:​ локации-обработчики событий (и локация-счётчик). 
 + 
 +Любая локация,​ названная как угодно, ​и написанная каким угодно образом,​ может быть назначена обработчикомобытия или локацией-счётчиком. Для этого название этой локации нужно ​прописать в специальную системную переменную. Например:​ 
 + 
 +<sxh qsp> 
 +$counter = '​счётчик'​ & ! назначаем локацию-счётчик 
 +$onobjsel = '​onClick'​ & ! назначаем локацию-обработчик события "​Выделение предмета"​ 
 +$usercom = '​debugger'​ & ! назначаем локацию-обработчик события "​Нажатие клавиши ввода в Поле ввода"​ 
 +</​sxh>​ 
 + 
 +Как видите, название локации может быть совершенно любым, главное, чтобы она была прописана в нужную системную переменную. И как только это происходит,​ как только мы прописываем имя локации в нужную переменную,​ эта локация становится **связана** с указанным событием. Это значит,​ что как только это событие случится,​ будет выполнен код на указанной локации. 
 + 
 +Подробнее о том, ​какая системная переменная за **связку** с каким событием отвечает, вы можете прочитать в статье [[help:​service_locations|"​Служебные локации"​]]. 
 + 
 +Чтобы отвязать локацию от событиядостаточно в нужную системную переменную ​прописать пустое значение:​ 
 + 
 +<sxh qsp> 
 +$counter = ''​ & ! отключаем локацию-счётчик 
 +$onobjsel = ''​ & ! отключаем локацию-обработчик события "Выделение предмета" 
 +</​sxh>​ 
 + 
 +===== Процессы в настоящем времени ===== 
 + 
 +Если ​была назначена локация-счётчик,​ то с приблизительно ​равной периодичностью ​будет происходить вызов указанной ​локации-счётчика. По умолчанию локация-счётчик вызывается 2 раза в секунду,​ то есть каждые 500 миллисекунд — это значение можно изменять с помощью оператора **''​SETTIMER''​**. 
 + 
 +<sxh qsp> 
 +settimer 100 & ! устанавливаем период обращения к локации-счётчику в 100 мс 
 +$counter = '​отсчёт_времени'​ & ! плеер будет вызывать локацию **отсчёт времени** примерно 10 раз в секунду 
 +</​sxh>​ 
 + 
 +Так же с заданной периодичностью (по умолчанию 2 раза ​в секунду) происходит полное обновление интерфейса:​ шрифт и цвета, заданные с помощью системных переменных. 
 + 
 +Подробнее о локации-счётчике и создании игровых событий в реальном времени читайте в статье [[help:​realtime|"​Реальное время"​]]. 
 + 
 +[[help:​variables|Вперёд:​ Переменные]]
  
----- 
-Вперёд:​ 
help/principle.1383399715.txt.gz · Последние изменения: 2013/11/02 17:41 (внешнее изменение)