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

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


help:principle

Различия

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

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

Both sides previous revision Предыдущая версия
Следущая версия
Предыдущая версия
help:principle [2013/11/02 13:28]
newsash
help:principle [2024/10/14 07:28] (текущий)
aleks_versus проба обновления до 5.9.0
Строка 1: Строка 1:
-[[help:jump|Назад:​ Переходы внутри локации,​ циклы]] +[[help:objs|Назад:​ Предметы]]
-=====Порядок работы интерпретатора=====+
  
-При обработке новой локации (например,​ при переходе с помощью операторов "GOTO, XGOTO, GOSUB"​) выполняются следующие действия:​ +====== ​Порядок работы интерпретатора ​======
-  - Очистка списка действий предыдущей локации, если был осуществлен непосредственный переход на локацию (например,​ с помощью операторов "GOTO, XGOTO"​);​ +
-  - Обновление поля описания локации (замена существующего основного описания,​ либо добавление к нему текста базового описания новой локации - в зависимости от того, каким образом был произведён переход);​ +
-  - Добавление базовых действий новой локации;​ +
-  - Последовательное выполнение операторов,​ находящихся в поле "​Выполнить ​при посещении";​ +
-  - При непосредственном переходе на локацию выполняется обработка локации-обработчика перехода на новую локацию,​ если таковая указана;​ +
-  - Если переменная локации-счётчика не пуста, то происходит обработка соответствующей локации (по умолчанию,​ 2 раза в секунду);​ +
-  - Обновление интерфейса (шрифт,​ цвета, заданные с помощью системных переменных) - также, по умолчанию,​ 2 раза в секунду;​ +
-  - При выборе действия или предмета пользователем,​ происходит обработка локаций-обработчиков выбора действий и предметов;​ +
-  - При загрузке или сохранении состояния игры, происходит обработка локаций-обработчиков загрузки и сохранения игры; +
-  - Если пользователь щёлкает на действии,​ то выполняются операторы,​ определённые для этого действия;​ +
-  - Если пользователь нажимает "​Enter"​ в строке ввода, то происходит обработка локации-обработчика строки ввода.+
  
 +**Несмотря на то, что эта статья обросла некоторыми подробностями,​ она всё ещё требует серьёзной редактуры,​ упрощения и расширения. Так что пока что это всё ещё черновой вариант.**
  
 +Эта статья подробно рассказывает о порядке работы интерпретатора (плеера) **QSP**. Она может показаться вам довольно сложной,​ но читать её всю не обязательно. Вернитесь к ней, когда у вас возникнут сложности в понимании того, как ведёт себя плеер. А пока достаточно ознакомиться с общими принципами:​
  
-Системные переменные +  * При запуске игры автоматически воспроизводится только самая первая ​в игре локация. На остальные локации нужно ​осуществлять ​переходы с помощью **''​GOTO''​** или **''​XGOTO''​**,​ или вызывать их с помощью **''​GOSUB''​**,​ **''​FUNC''​**,​ или иным предусмотренным плеером способом. 
-Системные ​переменные - переменные, ​значения которых ​обрабатываются интерпретатором специальным образом. Системные переменные используются как ​обычные переменные, т.е. в них ​можно заносить и считывать ​из них значения (правда стоит помнитьчто в результате вы можете получитьнапример, чёрный цвет текста на чёрном же фоне - и ничего не будет видно).+  * Код действий "прикрепляется"​ к действию и не выполняетсяпока игрок не нажмёт на действие
 +  * Все команды ​выполняются последовательно одна за другойи никогда не выполняются одновременно.
  
 +Ниже по тексту будут использоваться следующие определения:​
  
-Базовые системные переменные ​основные переменные. +  * **Переход на локацию** — это событие в игре, которое происходит при обращении к локации с помощью операторов **''​GOTO''​** или **''​XGOTO''​**. При этом локация становится "​активной",​ или "​текущей"​. Функция **''​$CURLOC''​** возвращает название локации,​ на которую был совершён переход,​ а массив **''​ARGS[]''​** этой локации сохраняет свои значения,​ пока снова не будет осуществлён переход на локацию (другую,​ или ту же самую). После добавления текста из поля "​Базовое описание"​ в Окно основного описания,​ действий из поля "**Базовые ​действия**" в **Окно действий**, и выполнения кода из поля "​**Выполнить при посещении**",​ плеер "​останавливается"​ и ожидает участия игрока,​ при этом локация, ​на которую был осуществлён ​переход, остаётся "​активной"​ ("​текущей"​),​ т.е. функция **''​$CURLOC''​** в любой момент может вернуть название этой локации,​ а массив ''​ARGS[]''​ сохраняет значения.\\ Для переходов существуют только два оператора (подробнее см. статью [[help:​goto|"​Переходы"​]]):​ 
-Переменные,​ задающие обработчики событий - позволяют обрабатывать такие события,​ как выбор предмета,​ переход на новую локацию,​ ввод строки в поле ввода... +    * **''​GOTO''​** — осуществляет переход на указанную локацию с автоматической очисткой **Окна ​основного описания** и **Окна действий**. 
-Переменные настройки интерфейса - позволяют настраивать цвета, шрифт, а также использовать в описаниях ​HTML.+    * **''​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|Вперёд:​ Переменные]]
  
-PS: 
-При использовании операторов "​KILLALL,​ KILLVAR"​ удаляются также все системные переменные. 
help/principle.1383398889.txt.gz · Последние изменения: 2013/11/02 17:28 (внешнее изменение)