Здесь показаны различия между двумя версиями данной страницы.
Both sides previous revision Предыдущая версия | |||
help:organizing [2024/03/18 10:17] aleks_versus |
help:organizing [2024/10/14 11:40] (текущий) aleks_versus обновление 5.9.0 |
||
---|---|---|---|
Строка 1: | Строка 1: | ||
- | |||
[[help:conditional|Назад: Условия]] | [[help:conditional|Назад: Условия]] | ||
====== Пользовательские функции и процедуры ====== | ====== Пользовательские функции и процедуры ====== | ||
- | |||
===== Общая информация о GOSUB и FUNC ===== | ===== Общая информация о GOSUB и FUNC ===== | ||
- | Сам принцип написания игр на **QSP** предполагает, что игра будет состоять из отдельных блоков кода — локаций. Эти локации могут быть связаны между собой переходами с помощью операторов ''**GOTO**'' и ''**XGOTO**''. Таким образом в **QSP** реализуется перемещение по игре, например, перемещение с места на место, или по главам интерактивной истории. | + | Сам принцип написания игр на **QSP** предполагает, что игра будет состоять из отдельных блоков кода — локаций. Эти локации могут быть связаны между собой переходами с помощью операторов ''%%GOTO%%'' и ''%%XGOTO%%''. Таким образом в **QSP** реализуется перемещение по игре, например, перемещение с места на место, или по главам интерактивной истории. |
- | Однако иногда нам необходимо использовать локации не как локации мест, не как главы или страницы, а для того, чтобы иметь возможность выполнять повторяющиеся фрагменты кода. Например, мы пишем на нескольких разных локациях действие подъёма яблок. И нам нужно, чтобы это действие добавляло предмет "Яблоки", если мы не поднимали ещё ни одного яблока, увеличивало число яблок у нас в рюкзаке, и уменьшало на соответствующей локации. | + | Однако иногда нам необходимо использовать локации не как локации мест, не как главы или страницы, а для того, чтобы иметь возможность выполнять повторяющиеся фрагменты кода. Например, мы пишем на нескольких разных локациях действие подъёма яблок. И нам нужно, чтобы это действие увеличивало число яблок у нас в рюкзаке, уменьшало на соответствующей локации и добавляло предмет "Яблоки", если мы не поднимали ещё ни одного яблока. |
- | В принципе мы это можем сделать просто копируя на каждую локацию вот такое действие: | + | В принципе мы это можем сделать, просто копируя на каждую локацию вот такое действие: |
<sxh qsp> | <sxh qsp> | ||
act "Взять яблоко": | act "Взять яблоко": | ||
- | if яблоки['рюкзак']=0: | + | if яблоки['рюкзак']=0: |
- | addobj "Яблоки" | + | addobj "Яблоки" |
- | end | + | end |
- | яблоки['рюкзак']+=1 | + | яблоки['рюкзак'] += 1 |
- | яблоки[$curloc]-=1 | + | яблоки[$curloc] -= 1 |
end | end | ||
</sxh> | </sxh> | ||
Строка 25: | Строка 23: | ||
Но посмотрите, сколько строчек кода это действие занимает. Семь. Если мы скопируем такое действие два или три раза, это ещё ничего, но что, если нам придётся копировать действие сто раз? Это семь сотен строчек кода. Это попросту увеличивает объём нашей игры в десятки раз. А ведь у нас может быть не одно такое действие. | Но посмотрите, сколько строчек кода это действие занимает. Семь. Если мы скопируем такое действие два или три раза, это ещё ничего, но что, если нам придётся копировать действие сто раз? Это семь сотен строчек кода. Это попросту увеличивает объём нашей игры в десятки раз. А ведь у нас может быть не одно такое действие. | ||
- | Чтобы нам не приходилось писать одинаковый код множество и множество раз, в **QSP** предусмотрены специальный оператор ''**GOSUB**'' и специальная функция ''**FUNC**'', которые позволяют нам превращать любые локации в свобственные процедуры и функции. В данном случае мы можем вынести код действия в отдельную локацию, назвать эту локацию ''"поднять_яблоко"'', а затем вызывать эту локацию из действия с помощью ''**GOSUB**''. | + | Чтобы нам не приходилось писать одинаковый код множество и множество раз, в **QSP** предусмотрены специальный оператор ''%%GOSUB%%'' и специальная функция ''%%FUNC%%'', которые позволяют нам превращать любые локации в собственные процедуры и функции. В данном случае мы можем вынести код действия в отдельную локацию, назвать эту локацию ''%%"поднять_яблоко"%%'', а затем вызывать эту локацию из действия с помощью ''%%GOSUB%%''. |
+ | |||
+ | Локация ''%%"поднять_яблоко"%%'': | ||
- | Локация ''"поднять_яблоко"'': | ||
<sxh qsp> | <sxh qsp> | ||
!# поднять_яблоко | !# поднять_яблоко | ||
if яблоки['рюкзак']=0: | if яблоки['рюкзак']=0: | ||
- | addobj "Яблоки" | + | addobj "Яблоки" |
end | end | ||
яблоки['рюкзак']+=1 | яблоки['рюкзак']+=1 | ||
Строка 38: | Строка 37: | ||
Действие, которое мы пишем на любой другой локации: | Действие, которое мы пишем на любой другой локации: | ||
+ | |||
<sxh qsp> | <sxh qsp> | ||
act "Взять яблоко": | act "Взять яблоко": | ||
- | gosub "поднять_яблоко" | + | gosub "поднять_яблоко" |
end | end | ||
</sxh> | </sxh> | ||
Строка 46: | Строка 46: | ||
Как видите, всё наше действие сократилось до трёх строчек кода, а сам код подъёма яблока написан нами всего один раз! | Как видите, всё наше действие сократилось до трёх строчек кода, а сам код подъёма яблока написан нами всего один раз! | ||
- | (Подробнее о том, как работает оператор ''**GOSUB**'' вы можете прочитать в разделе ниже). | + | (Подробнее о том, как работает оператор ''%%GOSUB%%'' вы можете прочитать в разделе ниже). |
Ну а если, предположим, нам нужно написать сразу три действия по подъёму яблок? И все три эти действия отличаются только числом яблок, которые мы поднимаем: | Ну а если, предположим, нам нужно написать сразу три действия по подъёму яблок? И все три эти действия отличаются только числом яблок, которые мы поднимаем: | ||
Строка 52: | Строка 52: | ||
<sxh qsp> | <sxh qsp> | ||
act "Взять одно яблоко": | act "Взять одно яблоко": | ||
- | if яблоки['рюкзак']=0: | + | if яблоки['рюкзак']=0: |
- | addobj "Яблоки" | + | addobj "Яблоки" |
- | end | + | end |
- | яблоки['рюкзак']+=1 | + | яблоки['рюкзак']+=1 |
- | яблоки[$curloc]-=1 | + | яблоки[$curloc]-=1 |
end | end | ||
act "Взять два яблока": | act "Взять два яблока": | ||
- | if яблоки['рюкзак']=0: | + | if яблоки['рюкзак']=0: |
- | addobj "Яблоки" | + | addobj "Яблоки" |
- | end | + | end |
- | яблоки['рюкзак']+=2 | + | яблоки['рюкзак']+=2 |
- | яблоки[$curloc]-=2 | + | яблоки[$curloc]-=2 |
end | end | ||
act "Взять пять яблок": | act "Взять пять яблок": | ||
- | if яблоки['рюкзак']=0: | + | if яблоки['рюкзак']=0: |
- | addobj "Яблоки" | + | addobj "Яблоки" |
- | end | + | end |
- | яблоки['рюкзак']+=5 | + | яблоки['рюкзак']+=5 |
- | яблоки[$curloc]-=5 | + | яблоки[$curloc]-=5 |
end | end | ||
</sxh> | </sxh> | ||
Строка 76: | Строка 76: | ||
Вроде бы код здесь тоже повторяется, но не совсем. Что же делать? | Вроде бы код здесь тоже повторяется, но не совсем. Что же делать? | ||
- | И для таких ситуаций в **QSP** уже предусмотрен специальный механизм. Дело в том, что оператор ''**GOSUB**'' позволяет передавать на локацию, которую мы с его помощью вызываем, различные значения. В данном случае нам нужно передавать на локацию ''"поднять_яблоко"'', которую мы писали в предыдущем примере, число яблок. В действиях это будет выглядеть вот так: | + | И для таких ситуаций в **QSP** уже предусмотрен специальный механизм. Дело в том, что оператор ''%%GOSUB%%'' позволяет передавать на локацию, которую мы с его помощью вызываем, различные значения. В данном случае нам нужно передавать на локацию ''%%"поднять_яблоко"%%'', которую мы писали в предыдущем примере, число яблок. В действиях это будет выглядеть вот так: |
<sxh qsp> | <sxh qsp> | ||
act "Взять одно яблоко": | act "Взять одно яблоко": | ||
- | gosub "поднять_яблоко",1 | + | gosub "поднять_яблоко",1 |
end | end | ||
act "Взять два яблока": | act "Взять два яблока": | ||
- | gosub "поднять_яблоко",2 | + | gosub "поднять_яблоко",2 |
end | end | ||
act "Взять пять яблок": | act "Взять пять яблок": | ||
- | gosub "поднять_яблоко",5 | + | gosub "поднять_яблоко",5 |
end | end | ||
</sxh> | </sxh> | ||
- | Через запятую после названия локации мы можем перечислять различные значения (строковые и числовые), и эти значения будут переданы на указанную локацию. Однако где на локации ''"поднять_яблоко"'' нам искать эти переданные значения? | + | Через запятую после названия локации мы можем перечислять различные значения (строковые, числовые, кортежи), и эти значения будут переданы на указанную локацию. Однако где на локации ''%%"поднять_яблоко"%%'' нам искать эти переданные значения? |
- | Всё просто. Значения, которые мы передаём на локацию таким образом, автоматически помещаются в массив ''**ARGS**'', в ячейки, начиная с нулевой. И получается, что нам надо искать наше значение в ''**ARGS[0]**'': | + | Всё просто. Значения, которые мы передаём на локацию таким образом, автоматически помещаются в массив ''%%ARGS%%'', в ячейки, начиная с нулевой. И получается, что нам надо искать наше значение в ''%%ARGS[0]%%'': |
<sxh qsp> | <sxh qsp> | ||
!# поднять_яблоко | !# поднять_яблоко | ||
- | if яблоки['рюкзак']=0: | + | if яблоки['рюкзак'] = 0: |
- | addobj "Яблоки" | + | addobj "Яблоки" |
end | end | ||
- | яблоки['рюкзак']+=args[0] | + | яблоки['рюкзак'] += args[0] |
- | яблоки[$curloc]-=args[0] | + | яблоки[$curloc] -= args[0] |
</sxh> | </sxh> | ||
- | Можно передавать до девятнадцати любых значений на локацию и искать их на этой локации в массиве ''**ARGS**'' соответственно в ячейках с нулевой по восемнадцатую. Вот ещё пример передачи аргументов: | + | Можно передавать до девятнадцати любых значений на локацию и искать их на этой локации в массиве ''%%ARGS%%'' соответственно в ячейках с нулевой по восемнадцатую. Вот ещё пример передачи аргументов: |
+ | |||
+ | Локация ''%%"Приготовить"%%'': | ||
- | Локация ''"Приготовить"'': | ||
<sxh qsp> | <sxh qsp> | ||
!# приготовить | !# приготовить | ||
Строка 112: | Строка 113: | ||
А вот пример вызова этой локации из действий: | А вот пример вызова этой локации из действий: | ||
+ | |||
<sxh qsp> | <sxh qsp> | ||
act "Завтрак": | act "Завтрак": | ||
- | gosub "Приготовить","яичницу","с луком","на завтрак" | + | gosub "Приготовить","яичницу","с луком","на завтрак" |
end | end | ||
act "Обед": | act "Обед": | ||
- | gosub "Приготовить","гуляш","с овощами","в обед" | + | gosub "Приготовить","гуляш","с овощами","в обед" |
end | end | ||
act "Ужин": | act "Ужин": | ||
- | gosub "Приготовить","салат","с креветками","на ужин" | + | gosub "Приготовить","салат","с креветками","на ужин" |
end | end | ||
</sxh> | </sxh> | ||
- | Иногда нам нужно не только передать данные на локацию, но и получить с неё какие-то данные назад. Для этого случая нужно воспользоваться специальной функцией ''**FUNC**''. | + | Иногда нам нужно не только передать данные на локацию, но и получить с неё какие-то данные назад. Для этого случая нужно воспользоваться специальной функцией ''%%FUNC%%''. |
- | Как и ''**GOSUB**'', эта функция вызывает локацию, чтобы выполнить на ней какой-то код, однако, в отличие от ''**GOSUB**'', ''**FUNC**'' может вернуть значение из локации. | + | Как и ''%%GOSUB%%'', эта функция вызывает локацию, чтобы выполнить на ней какой-то код, однако, в отличие от ''%%GOSUB%%'', ''%%FUNC%%'' может вернуть значение из локации. |
- | Чтобы локация, вызванная с помощью ''**FUNC**'', вернула какое-то значение, мы должны на этой локации присвоить это значение переменной ''**RESULT**''. Например, мы хотим написать локацию, на которую будем передавать число, и чтобы эта локация возвращала нам квадрат переданного числа (то есть число умноженное на само себя). Назовём эту локацию ''"sqr"'': | + | Чтобы локация, вызванная с помощью ''%%FUNC%%'', вернула какое-то значение, мы должны на этой локации присвоить это значение переменной ''%%RESULT%%''. Например, мы хотим написать локацию, на которую будем передавать число, и чтобы эта локация возвращала нам квадрат переданного числа (то есть число умноженное на само себя). Назовём эту локацию ''%%"sqr"%%'': |
<sxh qsp> | <sxh qsp> | ||
Строка 135: | Строка 137: | ||
</sxh> | </sxh> | ||
- | Как видите, на локации ''"sqr"'' мы умножаем число из ''**ARGS[0]**'' само на себя, а затем результат присваиваем переменной ''**RESULT**''. Именно значение из переменной ''**RESULT**'' локация ''"sqr"'' вернёт с помощью функции ''**FUNC**'' на любой другой локации: | + | Как видите, на локации ''%%"sqr"%%'' мы умножаем число из ''%%ARGS[0]%%'' само на себя, а затем результат присваиваем переменной ''%%RESULT%%''. Именно значение из переменной ''%%RESULT%%'' локация ''%%"sqr"%%'' вернёт с помощью функции ''%%FUNC%%'' на любой другой локации: |
<sxh qsp> | <sxh qsp> | ||
Строка 143: | Строка 145: | ||
</sxh> | </sxh> | ||
- | Во всех приведённых примерах функцией является ''**FUNC**'', а оператором — ''**GOSUB**'', однако для удобства допустимо называть функциями именно локации, которые мы вызываем с помощью ''**GOSUB**'' или ''**FUNC**''. Например: «Я написал функцию "поднять_яблоко"». | + | Во всех приведённых примерах функцией является ''%%FUNC%%'', а оператором — ''%%GOSUB%%'', однако для удобства допустимо называть функциями именно локации, которые мы вызываем с помощью ''%%GOSUB%%'' или ''%%FUNC%%''. Например: «//Я написал функцию "поднять_яблоко"//». |
===== Описание GOSUB ===== | ===== Описание GOSUB ===== | ||
- | ''**GOSUB**'' — выполнение кода указанной локации без непосредственного перехода на неё. | + | ''%%GOSUB%%'' — выполнение кода указанной локации без непосредственного перехода на неё. |
Общая запись: | Общая запись: | ||
+ | |||
<sxh qsp> | <sxh qsp> | ||
- | GOSUB [$локация],[аргумент 0],[аргумент 1], ... ,[аргумент 18] | + | GOSUB [$локация],[аргумент 0],[аргумент 1], ... ,[аргумент 18] |
</sxh> | </sxh> | ||
- | , где ''[$локация]'' — это название локации, код которой мы хотим выполнить без непосредственного перехода на неё. Значения ''[аргумент 0]'', ''[аргумент 1]'' и т.д. могут использоваться на этой локации, их значения автоматически помещаются в ячейки массива ''ARGS[0]'', ''ARGS[1]'', и т.д. соответственно. После обработки локации предыдущие значения ''**ARGS**'' восстанавливаются. Использование аргументов не обязательно. | ||
- | Оператор имеет краткую форму ''**GS**'': | + | , где ''%%[$локация]%%'' — это название локации, код которой мы хотим выполнить без непосредственного перехода на неё. Значения ''%%[аргумент 0]%%'', ''%%[аргумент 1]%%'' и т.д. могут использоваться на этой локации, их значения автоматически помещаются в ячейки массива ''%%ARGS[0]%%'', ''%%ARGS[1]%%'', и т.д. соответственно. После обработки локации предыдущие значения ''%%ARGS%%'' восстанавливаются. Использование аргументов не обязательно. |
+ | |||
+ | Оператор имеет краткую форму ''%%GS%%'': | ||
<sxh qsp> | <sxh qsp> | ||
- | GS [$локация],[аргумент 0],[аргумент 1], ... ,[аргумент 18] | + | GS [$локация],[аргумент 0],[аргумент 1], ... ,[аргумент 18] |
</sxh> | </sxh> | ||
Строка 164: | Строка 168: | ||
<sxh qsp> | <sxh qsp> | ||
- | GOSUB ([$локация],[аргумент 0],[аргумент 1], ... ,[аргумент 18]) | + | GOSUB([$локация],[аргумент 0],[аргумент 1], ... ,[аргумент 18]) |
</sxh> | </sxh> | ||
- | При вызове указанной локации с помощью ''**GOSUB**'' происходит следующее: | + | При вызове указанной локации с помощью ''%%GOSUB%%'' происходит следующее: |
- | * Плеер прерывает выполнение текущего кода (например, кода текущей локации), и обращается к указанной локации | + | |
- | * Базовое описание и список действий указанной локации добавляются к описанию и действиям текущей локации. | + | * Плеер прерывает выполнение текущего кода (например, кода текущей локации), и обращается к указанной локации |
- | * Выполненяется код из поля **Выполнить при посещении** | + | * Базовое описание и список действий указанной локации добавляются к описанию и действиям текущей локации. |
- | * Затем плеер возвращается к выполнению кода, который прервал, к команде сразу после оператора ''**GOSUB**''. | + | * Выполненяется код из поля **Выполнить при посещении** |
+ | * Затем плеер возвращается к выполнению кода, который прервал, к команде сразу после оператора ''%%GOSUB%%''. | ||
- | На каждой локации автоматически создаётся собственный уникальный массив ''**ARGS**'', поэтому значения в этом массиве для каждой локации будут свои собственные. После выполнения кода локации, вызванной по ''**GOSUB**'', массив ''**ARGS**'' этой локации уничтожается. | + | На каждой локации автоматически создаётся собственный уникальный массив ''%%ARGS%%'', поэтому значения в этом массиве для каждой локации будут свои собственные. После выполнения кода локации, вызванной по ''%%GOSUB%%'', массив ''%%ARGS%%'' этой локации уничтожается. |
- | Обратите внимание! Значения из массива ''**ARGS**'' с локации, вызванной через GOSUB, не транслируются в блоки ''**ACT**''. В блоки ''**ACT**'' транслируются значения ''**ARGS**'' из текущей локации, т.е. локации, на которую был осуществлён переход с помощью операторов ''**GOTO**''/''**XGOTO**''. | + | **Обратите внимание!** Значения из массива ''%%ARGS%%'' с локации, вызванной через GOSUB, не транслируются в блоки ''%%ACT%%''. В блоки ''%%ACT%%'' транслируются значения ''%%ARGS%%'' из текущей локации, т.е. локации, на которую был осуществлён переход с помощью операторов ''%%GOTO%%''/''%%XGOTO%%''. |
<sxh qsp> | <sxh qsp> | ||
#начало | #начало | ||
- | $args[0]='локация начало' | + | $args[0] = 'локация начало' |
gosub 'переход', 'локация переход' | gosub 'переход', 'локация переход' | ||
- | - | ||
Строка 192: | Строка 197: | ||
Другие примеры: | Другие примеры: | ||
- | <sxh qsp> | ||
+ | <sxh qsp> | ||
! обработка локации "ход" | ! обработка локации "ход" | ||
! На локацию не переадются аргументы | ! На локацию не переадются аргументы | ||
Строка 211: | Строка 216: | ||
===== Описание FUNC ===== | ===== Описание FUNC ===== | ||
- | ''**FUNC**'' — выполнение кода указанной локации без непосредственного перехода на неё с возвращением значения. | + | ''%%FUNC%%'' — выполнение кода указанной локации без непосредственного перехода на неё с возвращением значения. |
Общая запись: | Общая запись: | ||
+ | |||
<sxh qsp> | <sxh qsp> | ||
- | FUNC([$локация],[аргумент 0],[аргумент 1], ... ,[аргумент 18]) | + | FUNC([$локация],[аргумент 0],[аргумент 1], ... ,[аргумент 18]) |
- | $FUNC([$локация],[аргумент 0],[аргумент 1], ... ,[аргумент 18]) | + | $FUNC([$локация],[аргумент 0],[аргумент 1], ... ,[аргумент 18]) |
+ | %FUNC([$локация],[аргумент 0],[аргумент 1], ... ,[аргумент 18]) | ||
</sxh> | </sxh> | ||
- | , где ''[$локация]'' — это название локации, код которой мы хотим выполнить без непосредственного перехода на неё. Аргументы ''[аргумент 0]'', ''[аргумент 1]'' и т.д. могут использоваться на этой локации, их значения автоматически помещаются в ячейки массива ''ARGS[0]'', ''ARGS[1]'', и т.д. соответственно. Название локации и аргументы должны обязательно заключаться в скобки. | + | , где ''%%[$локация]%%'' — это название локации, код которой мы хотим выполнить без непосредственного перехода на неё. Аргументы ''%%[аргумент 0]%%'', ''%%[аргумент 1]%%'' и т.д. могут использоваться на этой локации, их значения автоматически помещаются в ячейки массива ''%%ARGS[0]%%'', ''%%ARGS[1]%%'', и т.д. соответственно. Название локации и аргументы должны обязательно заключаться в скобки. |
- | Чтобы ''**FUNC**'' вернула строковый результат, на указанной локации нужно присвоить этот результат переменной ''''**$RESULT**''''. Для возвращения числового результата, он должен быть присвоен переменной ''**RESULT**''. Следует помнить, что ''**$RESULT**'' и ''**RESULT**'' — это одна и та же переменная, но разных типов, поэтому если вы определили на локации и ''**$RESULT**'' и ''**RESULT**'', функция вернёт то значение, которое было записано в эту переменную последним. | + | Чтобы ''%%FUNC%%'' вернула строковый результат, на указанной локации нужно присвоить этот результат переменной ''%%$RESULT%%''. |
+ | |||
+ | Для возвращения числового результата, он должен быть присвоен переменной ''%%RESULT%%''. | ||
+ | |||
+ | Если нужно вернуть несколько значений, используется кортеж ''%%%RESULT%%''. | ||
+ | |||
+ | Следует помнить, что ''%%%RESULT%%'', ''%%$RESULT%%'' и ''%%RESULT%%'' — это одна и та же переменная, но разных типов, поэтому если вы определили на локации и ''%%%RESULT%%'', ''%%$RESULT%%'' и ''%%RESULT%%'', функция вернёт то значение, которое было записано в эту переменную последним. | ||
+ | |||
+ | Если переменной ''%%RESULT%%'' не было присвоено никакое значение, функция ничего не вернёт. И тут есть два варианта поведения плеера. | ||
+ | |||
+ | * Если функция ''%%FUNC%%'' стоит в каком либо выражении, вместо функции будет подставлено значение по умолчанию (пустая строка или ноль в зависимости от типа самого выражения). | ||
+ | * Если функция ''%%FUNC%%'' стоит сразу после неявного оператора, такой оператор будет проигнорирован, и на экран ничего выводиться не будет. Пример: | ||
- | Если переменной ''**RESULT**'' не было присвоено ни строковое, ни числовое значение, функция ничего не вернёт. И тут есть два варианта поведения плеера. | ||
- | * Если функция ''**FUNC**'' стоит в каком либо выражении, вместо функции будет подставлено значение по умолчанию (пустая строка или ноль в зависимости от типа самого выражения). | ||
- | * Если функция ''**FUNC**'' стоит сразу после неявного оператора, такой оператор будет проигнорирован, и на экран ничего выводиться не будет. Пример: | ||
<sxh qsp> | <sxh qsp> | ||
- | !# локация_Н | + | !# локация_Н |
- | N=23*13 | + | N = 23 * 13 |
- | ! ни одно значение не присваивается переменной result | + | ! ни одно значение не присваивается переменной result |
</sxh> | </sxh> | ||
+ | |||
<sxh qsp> | <sxh qsp> | ||
- | 'строка 1' | + | 'строка 1' |
- | func('локация_Н') &! ничего не выведется на экран | + | func('локация_Н') &! ничего не выведется на экран |
- | 'строка 2' | + | 'строка 2' |
- | 56+func('локация_Н') &! функция стоит в выражении. Её значение = 0 | + | 56 + func('локация_Н') &! функция стоит в выражении. Её значение = 0. На экране будет 56 |
</sxh> | </sxh> | ||
- | Не обязательно, но рекомендуется, записывать ключевое слово ''**FUNC**'' с символом ''**$**'', если функция должна вернуть текстовое значение, и без символа ''**$**'', если функция должна вернуть числовое значение: | + | Не обязательно, но рекомендуется, записывать ключевое слово ''%%FUNC%%'' с символом ''%%$%%'', если функция должна вернуть текстовое значение, и с символом ''%%%%%'', если функция должна вернуть кортеж. Это улучшит читаемость кода: |
<sxh qsp> | <sxh qsp> | ||
- | $func('срез_строки','Мы вышли из дома, когда во всех окнах погасли огни.',3,7) | + | $func('срез_строки','Мы вышли из дома, когда во всех окнах погасли огни.',3,7) |
- | func('возвести_в_степень',3,3) | + | func('возвести_в_степень',3,3) |
+ | $name, age, %coords = %func('get_pers', 'mjolnir') | ||
</sxh> | </sxh> | ||
- | При вызове указанной локации с помощью ''**FUNC**'' происходит следующее: | + | При вызове указанной локации с помощью ''%%FUNC%%'' происходит следующее: |
- | * Плеер прерывает выполнение текущего кода (например, кода текущей локации), и обращается к указанной локации | + | |
- | * Базовое описание и список действий указанной локации добавляются к описанию и действиям текущей локации. | + | |
- | * Выполненяется код из поля **Выполнить при посещении** | + | |
- | * Затем плеер возвращается к выполнению кода, который прервал. То есть к вычислению выражения, в котором стоит данная функция. | + | |
- | На каждой локации автоматически создаются свои собственные уникальные массивы ''**ARGS**'' и ''**RESULT**'', поэтому значения в этих массивах для каждой локации будут свои собственные. После выполнения кода локации, вызванной по ''**FUNC**'', массивы ''**ARGS**'' и ''**RESULT**'' этой локации уничтожаются. | + | * Плеер прерывает выполнение текущего кода (например, кода текущей локации), и обращается к указанной локации |
+ | * Базовое описание и список действий указанной локации добавляются к описанию и действиям текущей локации. | ||
+ | * Выполненяется код из поля **Выполнить при посещении** | ||
+ | * Затем плеер возвращается к выполнению кода, который прервал. То есть к вычислению выражения, в котором стоит данная функция. | ||
- | Обратите внимание! Значения из массивов ''**ARGS**'' и ''**RESULT**'' с локации, вызванной через ''**FUNC**'', не транслируются в блоки ''**ACT**''. В блоки ''**ACT**'' транслируются значения ''**ARGS**'' и ''**RESULT**'' из текущей локации, т.е. локации, на которую был осуществлён переход с помощью операторов ''**GOTO**''/''**XGOTO**''. | + | На каждой локации автоматически создаются свои собственные уникальные массивы ''%%ARGS%%'' и ''%%RESULT%%'', поэтому значения в этих массивах для каждой локации будут свои собственные. После выполнения кода локации, вызванной по ''%%FUNC%%'', массивы ''%%ARGS%%'' и ''%%RESULT%%'' этой локации уничтожаются. |
+ | Обратите внимание! Значения из массивов ''%%ARGS%%'' и ''%%RESULT%%'' с локации, вызванной через ''%%FUNC%%'', не транслируются в блоки ''%%ACT%%''. В блоки ''%%ACT%%'' транслируются значения ''%%ARGS%%'' и ''%%RESULT%%'' из текущей локации, т.е. локации, на которую был осуществлён переход с помощью операторов ''%%GOTO%%''/''%%XGOTO%%''. | ||
Примеры: | Примеры: | ||
+ | |||
<sxh qsp> | <sxh qsp> | ||
!Обработка локации "поднять_яблоко" как функции. | !Обработка локации "поднять_яблоко" как функции. | ||
Строка 270: | Строка 288: | ||
!$ARGS[0] содержит строку "строка", ARGS[1] равен 2. | !$ARGS[0] содержит строку "строка", ARGS[1] равен 2. | ||
MSG "text" + FUNC($name, "строка", 2) | MSG "text" + FUNC($name, "строка", 2) | ||
- | |||
</sxh> | </sxh> | ||
===== Ранний выход. Оператор EXIT ===== | ===== Ранний выход. Оператор EXIT ===== | ||
- | Чтобы прервать выполнение текущего кода и выйти из вызванной с помощью ''**GOSUB**'' или ''**FUNC**'' локации, используйте оператор ''**EXIT**''. | + | Чтобы прервать выполнение текущего кода и выйти из вызванной с помощью ''%%GOSUB%%'' или ''%%FUNC%%'' локации, используйте оператор ''%%EXIT%%''. |
- | ''**EXIT**'' - завершение выполнения текущего кода (преждевременный выход из подпрограммы / обработчика какого-либо события). | + | ''%%EXIT%%'' - завершение выполнения текущего кода (преждевременный выход из подпрограммы/обработчика какого-либо события). |
Пример: | Пример: | ||
+ | |||
<sxh qsp> | <sxh qsp> | ||
if args[0] = 0: exit | if args[0] = 0: exit | ||
Строка 286: | Строка 304: | ||
===== Неявный вызов функции FUNC ===== | ===== Неявный вызов функции FUNC ===== | ||
- | Вы можете не прописывать всякий раз функцию ''**FUNC**'' явно. Можно использовать более простую запись. Вот как это выглядит в общем виде: | + | Вы можете не прописывать всякий раз функцию ''%%FUNC%%'' явно. Можно использовать более простую запись. Вот как это выглядит в общем виде: |
<sxh qsp> | <sxh qsp> | ||
Строка 292: | Строка 310: | ||
</sxh> | </sxh> | ||
- | Здесь ''[$локация]'' — это название локации, код которой мы хотим выполнить без непосредственного перехода на неё. Аргументы ''[аргумент 0]='', ''[аргумент 1]'' и т.д. могут использоваться на этой локации, их значения автоматически помещаются в ячейки массива ''ARGS[0]'', ''ARGS[1]'', и т.д. соответственно. | + | Здесь ''%%[$локация]%%'' — это название локации, код которой мы хотим выполнить без непосредственного перехода на неё. Аргументы ''%%[аргумент 0]%%'', ''%%[аргумент 1]%%'' и т.д. могут использоваться на этой локации, их значения автоматически помещаются в ячейки массива ''%%ARGS[0]%%'', ''%%ARGS[1]%%'', и т.д. соответственно. |
- | То есть: пишем символ ''**@**'', затем без пробелов название локации, и сразу за названием локации в скобках через запятую перечисляем аргументы. | + | То есть: пишем символ ''%%@%%'', затем без пробелов название локации, и сразу за названием локации в скобках через запятую перечисляем аргументы. |
При такой записи необходимо соблюдать несколько правил: | При такой записи необходимо соблюдать несколько правил: | ||
- | * Название локации не должно содержать пробелов, символов математических операций и специальных символов (за исключением точки) | + | |
- | * Название локации не должно совпадать с ключевыми словами QSP, в том числе с названиями системных переменных. | + | * Название локации не должно содержать пробелов, символов математических операций и специальных символов (за исключением точки) |
- | * Аргументы, передаваемые на локацию, всегда должны заключаться в скобки | + | * Название локации не должно совпадать с ключевыми словами QSP, в том числе с названиями системных переменных. |
- | * Если на локацию не нужно передавать аргументы, после её названия можно поставить пустые скобки, а можно не ставить | + | * Аргументы, передаваемые на локацию, всегда должны заключаться в скобки |
- | * Нельзя подставить вместо названия локации значение переменной! | + | * Если на локацию не нужно передавать аргументы, после её названия можно поставить пустые скобки, а можно не ставить. |
+ | * Нельзя подставить вместо названия локации значение переменной! | ||
Примеры: | Примеры: | ||
Строка 312: | Строка 331: | ||
! функция не принимает аргументов | ! функция не принимает аргументов | ||
*pl @PI() &! можно указать пустые скобки | *pl @PI() &! можно указать пустые скобки | ||
- | *pl @PI &! можно не указывать пустые скобки | + | *pl @PI &! можно не указывать пустые скобки |
степень = @возвести_в_степень(3,3) | степень = @возвести_в_степень(3,3) | ||
Строка 320: | Строка 339: | ||
</sxh> | </sxh> | ||
- | Если подобный неявный вызов сочетается с использованием неявного оператора, а на локации при этом НЕ присваивается значение переменной ''**RESULT**'', можно использовать неявный вызов функции заместо оператора ''**GOSUB**'': | + | Если подобный неявный вызов сочетается с использованием неявного оператора, а на локации при этом НЕ присваивается значение переменной ''%%RESULT%%'', можно использовать неявный вызов функции вместо оператора ''%%GOSUB%%'': |
+ | |||
+ | Локация ''%%"поднять_яблоко"%%'': | ||
- | Локация ''"поднять_яблоко"'': | ||
<sxh qsp> | <sxh qsp> | ||
!# поднять_яблоко | !# поднять_яблоко | ||
if яблоки['рюкзак']=0: | if яблоки['рюкзак']=0: | ||
- | addobj "Яблоки" | + | addobj "Яблоки" |
end | end | ||
яблоки['рюкзак']+=1 | яблоки['рюкзак']+=1 | ||
Строка 333: | Строка 353: | ||
Действие, которое мы пишем на любой другой локации: | Действие, которое мы пишем на любой другой локации: | ||
+ | |||
<sxh qsp> | <sxh qsp> | ||
act "Взять яблоко": | act "Взять яблоко": | ||
- | @поднять_яблоко & ! в данном случае поведение функции будет идентично поведению ''**GOSUB**'' | + | @поднять_яблоко & ! в данном случае поведение функции будет идентично поведению GOSUB |
end | end | ||
</sxh> | </sxh> | ||
Строка 341: | Строка 362: | ||
===== Локальные переменные ===== | ===== Локальные переменные ===== | ||
- | На любой локации вы можете назначать локальные переменные, которые будут существовать только в момент выполнения кода этих локаций, а после — автоматически уничтожатся. Значения в этих локальных переменных не пересекаются со значениями одноимённых переменных в других локациях. | + | На любой локации вы можете назначать локальные переменные, которые будут существовать только в момент выполнения кода этих локаций, а после — автоматически уничтожаться. Значения в этих локальных переменных не пересекаются со значениями одноимённых переменных в других локациях. |
См. раздел "Локальные переменные" в разделе [[help:variables|Переменные]]. | См. раздел "Локальные переменные" в разделе [[help:variables|Переменные]]. | ||
Строка 349: | Строка 370: | ||
Таким образом вы можете разбивать свой код на множество более мелких блоков, дабы избегать повторения одинаковых фрагментов. Это позволяет не только лучше структурировать код, но и улучшает его читаемость и позволяет разрабатывать его модульно, т.е. отдельными независимыми фрагментами. Это, в свою очередь, ускоряет отладку и написание больших и сложных механик для ваших игр. | Таким образом вы можете разбивать свой код на множество более мелких блоков, дабы избегать повторения одинаковых фрагментов. Это позволяет не только лучше структурировать код, но и улучшает его читаемость и позволяет разрабатывать его модульно, т.е. отдельными независимыми фрагментами. Это, в свою очередь, ускоряет отладку и написание больших и сложных механик для ваших игр. | ||
- | Так же см. [[https://aleksversus.github.io/howdo_faq/articles/operatory_funktsii_argumenty_0006.html|большую статью по операторам, функциям и аргументам]]. | + | Так же см. [[https://aleksversus.github.io/howdo_faq/docs/articles/operators_funcs_args/|большую статью по операторам, функциям и аргументам]]. |
[[help:jump|Вперёд: Переходы внутри локации]] | [[help:jump|Вперёд: Переходы внутри локации]] | ||
- | |||