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

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


help:principle

Различия

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

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

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