Метки и поток управления (Labels & Control Flow)

Материал из Ren'Py Wiki
Перейти к навигации Перейти к поиску

Оператор 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" на английском языке.


На главную страницу Официальная документация движка Вернуться к началу статьи