Метки и поток управления (Labels & Control Flow)
Оператор label (Label Statement)[править | править код]
Операторы label позволяют присвоить имя любому месту в программе. Операторы создаются исключительно для вызова или перехода к нужному месту с помощью метки либо из скрипта Ren'Py, либо функции в Python или из экранов.
label sample1:
"Вот метка 'sample1'."
label sample2(a="default"):
"Это метка 'sample2'."
"a = [a]"
Оператор label может иметь связанный с ним блок. В таком случае управление переходит к блоку при достижении начала оператора label и переходит к оператору, следующему за оператором label, при достижении конца данного блока.
Существует два вида меток:
- Глобальная метка
- Глобальные метки существуют в одной глобальной области видимости во всех файлах проекта, поэтому они должны иметь уникальные имена в каждой игре.
- Локальная метка
- Если следовать логике, то локальные метки находятся внутри области видимости глобальной метки, в которой они объявлены. Чтобы объявить локальную метку, перед её именем необходимо поставить точку. Например:
label global_label:
"Внутри глобальной метки..."
label .local_name:
"...находится локальная метка."
jump .local_name
На локальные метки можно сослаться непосредственно в той же самой глобальной метке, в которой они были объявлены, или по их полному имени, состоящего из глобальных и локальный частей имени:
label another_global:
"Теперь давайте перейдём внутрь локальной метки, расположенной в другом месте."
jump global_label.local_name
Оператор label может принимать список дополнительных параметров. Эти параметры обрабатываются Ren'Py в соответствии с РЕР 3102 с учетом двух исключений:
- Значения параметров по умолчанию вычисляются во время вызова.
- Переменные относятся более к динамической, чем к лексической области видимости.
Оператор jump (Jump Statement)[править | править код]
Оператор jump используется для передачи управления заданной метке.
Если присутствует ключевое слово expression, следующее за ним выражение вычисляется, и полученная последовательность символов используется в качестве имени метки оператора, к которой требуется перейти. Если ключевое слово expression отсутствует, имя метки оператора, к которой требуется перейти, должно быть непосредственно задано.
В отличие от оператора call, оператор jump не помещает следующий за ним оператор в стек. В связи с этим невозможно вернуться туда, откуда был совершен переход.
label loop_start:
e "О нет! Это выглядит так, словно мы попали в ловушку бесконечного цикла."
jump loop_start
Оператор call (Call Statement)[править | править код]
Оператор call используется для передачи управления заданной метке. Он также помещает следующий за ним оператор в стек вызова, позволяя оператору return возвращать управление оператору, следующему за оператором call.
Если присутствует ключевое слово expression, выражение, следующее за ним, вычисляется и полученная последовательность символов используется в качестве имени метки для вызова. Если ключевое слово expression отсутствует, имя оператора для вызова должно быть непосредственно задано.
Если присутствуют необязательное предложение from, оно приводит к включению оператора label с заданным именем в качестве оператора, непосредственно следующего за оператором call. Четко обозначенная метка помогает гарантировать, что сохраненные игры со стеками возвратов смогут вернуться в надлежащее место при загрузке измененного скрипта.
e "Во-первых, мы вызовем subroutine."
call subroutine
call subroutine(2)
call expression "subroutine" pass (count=3)
# ...
label subroutine(count=1):
e "Я пришёл сюда [count] time(s)."
e "Далее мы вернёмся из subroutine."
return
Оператор call может принимать аргументы, обрабатываемые в соответствии с PEP 3102.
При использовании call expression со списком аргументов, ключевое слово pass должно быть вставлено между expression и списком аргументов. Иначе список аргументов будет обработан как часть выражения, а не как часть оператора call.
Оператор return (Return Statement)[править | править код]
Оператор return получает доступ к оператору, находящемуся на вершине вызова стека, извлекает и передает ему управление. Если стек вызова пуст, оператор return перезапускает Ren'Py, возвращая управление в главное меню.
label start:
"Небольшой пример использования оператор return от переводчиков"
return
Если для возврата используется дополнительное выражение, оно вычисляется и результат сохраняется в переменной _return. Эта переменная входит в динамическую область видимости для каждого контекста.
Специальные метки (Special Labels)[править | править код]
Ren'Py использует следующие метки:
- start
- По умолчанию Ren'Py переходит к этой метке при запуске игры.
label start: "Небольшой пример использования метки start от переводчиков."
- quit
- Если метка существует, то она вызывается в новом контексте, когда пользователь завершает игру.
label quit: if persistent.ghost_menu: hide screen main_menu scene white show image "sylvie.png": xpos -100 ypos -100 zoom 3.5 pause 0.01 return
- after_load
- Если метка существует, то она вызывается при загрузке игры. Метку можно использовать для исправления данных при обновлении игры.
label after_load: $ points = 0
- splashscreen
- Если метка существует, то она вызывается при первом запуске игры (до появления главного меню).
# фрагмент кода, представленный ниже, вставить ДО метки label start: label splashscreen: scene black #чёрный фон "Вам действительно 18 лет?" menu: "Да": show screen main_menu # переход в главное меню "Нет": $ renpy.quit() # выход из игры return
- before_main_menu
- Если метка существует, то она вызывается перед главным меню. Метка используется в редких случаях для настройки главного меню, например, начав воспроизведение видеоролика в фоновом режиме.
label before_main_menu: $ config.main_menu_music = audio.t1 return
- main_menu
- Если метка существует, то она вызывается вместо главного меню. Если присутствует оператор return, Ren'Py начнет игру с метки start. Например, следующий код немедленно начнёт игру, минуя главное меню.
label main_menu: return
- либо
label start: "Привет, мир!"
- after_warp
- Если метка существует, то вызывается после перемещения к строке, но до выполнения оператора перемещения. См. раздел «Перемещение к строке».
Функции меток и потока управления (Labels & Control Flow Functions)[править | править код]
renpy.call_in_new_context(label, *args, **kwargs)
- Создает новый контекст и начинает выполнение скрипта Ren'Py с заданной метки в этом контексте. Откат изменений недоступен в новом контексте и сохранение/загрузка произойдет в контексте верхнего уровня (фактически, вас будет возвращать в действующий контекст).
- Функция используется для начала еще одного взаимодействия с игроком. Используйте эту функцию для начала другого взаимодействия с пользователем внутри изначального взаимодействия.
renpy.get_all_labels()
- Возвращает набор всех используемых меток в программе, включая метки, определенные для внутреннего использования в библиотеках.
renpy.get_return_stack()
- Возвращает список данных текущего стека возвратов. Стек возвратов представляет собой список имён операторов.
- Имена операторов будут последовательностью символов (для меток) или непрозрачными кортежами (для операторов без меток).
renpy.has_label(name)
- Возвращает значение True, если name является допустимой меткой программы, иначе возвращается значение False.
- name
- Должно быть последовательностью символов для проверки наличия метки. Оно также может быть непрозрачным кортежем для указания имени оператора, не имеющему меток.
renpy.invoke_in_new_context(callable, *args, **kwargs)
- Создает новый контекст и вызывает заданную callable функцию языка программирования Python в этом контексте. Когда функция возвращает значение или вызывает исключение, то управление возвращается к исходному контексту. Данная функция обычно используется для вызова функции языка Python, которая должна отображать информацию игроку (например, запрос подтверждения) внутри обработчика событий.
- Контекст поддерживает состояние дисплея (включая то, как экраны и изображения отображаются) и аудиосистемы. Оба будут восстановлены при возврате контекста.
- Дополнительные и именованные аргументы передаются callable.
- Контекст, созданный с помощью этой функции, не может выполнить скрипт Ren'Py. Функции, которые могут привести к изменению поток скрипта Ren'Py, такие как renpy.jump(), обрабатываются внешним контекстом. Если вы хотите вызвать скрипт Ren'Py, а не функцию языка Python, используйте renpy.call_in_new_context().
renpy.jump_out_of_context(label)
- Приводит к тому, что управление покидает текущий контекст, а затем переносится в родительский контекст на заданную метку.
renpy.seen_label(label)
- Возвращает значение True, если именованная метка хотя бы раз выполнена в системе текущего пользователя, иначе возвращается значение False. Например, это может использоваться для разблокировки элементов галереи.
renpy.set_return_stack(stack)
- Задает текущий стек возвратов. Стек возвратов представляет собой список имён операторов.
- Имена оператора могут быть последовательностью символов (для меток) или непрозрачными кортежами (для операторов без меток).
Источник[править | править код]
Статья "Labels & Control Flow" на английском языке.
На главную страницу | Официальная документация движка | Вернуться к началу статьи |