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

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


help:organizing

Различия

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

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

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|Вперёд:​ Переходы внутри локации]]
- 
  
help/organizing.1710757039.txt.gz · Последние изменения: 2024/03/18 10:17 — aleks_versus