Диалоги и повествование
Текст — основа визуальных новелл и в целом довольно важен для сюжетно-ориентированных игр. Этот текст может состоять из диалогов, помеченных говорящим персонажем, и повествования, у которого нет говорящего. (Для удобства мы будем объединять диалоги и повествование под общим термином «диалог», за исключением случаев, когда различия важны.) Также важно, чтобы пользователь мог настраивать внешний вид диалога в соответствии со своей игрой.
В Ren'Py большинство диалогов пишется с помощью инструкций say. Внешний вид диалога можно настроить для каждого персонажа отдельно, используя объекты Character.
Инструкция say
Инструкция say используется для диалогов и повествования. Поскольку это почти
всегда самая часто используемая инструкция в скриптах Ren'Py, её синтаксис
минимизирует накладные расходы при написании. Вот несколько примеров инструкций say:
"This is narration."
"Eileen" "This is dialogue, with an explicit character name."
e "This is dialogue, using a character object instead."
"Bam!!" with vpunch
Первая форма инструкции say состоит из одной строки. Эта форма используется для повествования, где содержанием является сама строка.
Вторая форма состоит из двух строк. Первая строка — это имя говорящего персонажа, а вторая — произносимый диалог.
Третья форма состоит из простого выражения, за которым следует строка. Простое выражение должно вычисляться либо в строку, содержащую имя персонажа, либо в объект Character. В последнем случае объект Character используется для управления отображением диалога.
Последняя форма состоит из строки и предложения with, которое содержит переход. В этом случае строка отображается, и одновременно с этим экран сотрясается.
Хотя точные детали того, что делает инструкция say, контролируются используемым объектом персонажа, обычный эффект инструкции say — это отображение диалога на экране до тех пор, пока пользователь не кликнет, чтобы его закрыть, а затем удаление этого диалога с экрана.
Некоторые символы имеют для Ren'Py особое значение, поэтому их нельзя использовать
в строках диалога. Символ { начинает текстовый тег, а символ [ начинает
подстановку. Чтобы использовать их в диалоге, удваивайте их. Также может потребоваться
предварять кавычку обратным слэшем, чтобы она не закрывала строку. Например:
"I walked past a sign saying, \"Let's give it 100%%!\""
Также возможно использовать прокси-функцию вместо объекта персонажа. Подробнее об этом в этом разделе.
Определение объектов Character
Создавая объект Character и используя его в инструкции say, вы можете настраивать
внешний вид (и, в некоторой степени, поведение) диалога. Персонажи создаются
с помощью инструкции define для присваивания объекта Character переменной. Например:
define e = Character("Eileen", who_color="#c8ffc8")
После этого персонажа можно использовать в инструкции say:
e "Hello, world."
Character — это функция Python, которая принимает большое количество именованных аргументов. Эти именованные аргументы управляют поведением персонажа.
- Character(name=..., kind=adv, **args)
Создаёт и возвращает объект Character, который управляет внешним видом диалогов и повествования.
- name
Если строка, то это имя персонажа в диалоге. Когда name равно None, отображение имени опускается, как при повествовании. Если имя не задано, оно берётся из kind, а в противном случае по умолчанию равно None.
- kind
Персонаж (Character), на котором будет основан этот персонаж. При использовании значение по умолчанию для любого аргумента, не переданного этому персонажу, берётся из kind. Это можно использовать для определения шаблонного персонажа и последующего его копирования с изменениями.
Это также может быть пространство имён, в этом случае в качестве kind используется переменная 'character' из этого пространства имён.
Связанное изображение. С персонажем (Character) может быть связан тег изображения. Это позволяет инструкции say с этим персонажем отображать изображение с этим тегом, а также позволяет Ren'Py автоматически выбирать боковое изображение (side image) для показа, когда говорит этот персонаж.
- image
Строка с тегом изображения, связанного с этим персонажем.
Тег голоса. Если персонажу назначен тег голоса, связанные с ним голосовые файлы можно будет отключать или воспроизводить на экране настроек.
- voice_tag
Строка, которая позволяет отключать или воспроизводить голосовой файл, связанный с персонажем, в канале 'voice'.
Префиксы и суффиксы. Позволяют применять префикс и суффикс к имени персонажа и к отображаемому тексту. Это можно использовать, например, для добавления кавычек до и после каждой строки диалога.
- what_prefix
Строка, которая добавляется в начало реплики перед её отображением.
- what_suffix
Строка, которая добавляется в конец реплики перед её отображением.
- who_prefix
Строка, которая добавляется в начало имени персонажа перед его отображением.
- who_suffix
Строка, которая добавляется в конец имени персонажа перед его отображением.
Изменение отображения имени. Эти параметры помогают управлять отображением имени.
- dynamic
Если True, то name должен быть либо строкой, содержащей Python-выражение, либо функцией, либо вызываемым объектом. Если это строка, она будет вычисляться перед каждой репликой, и результат будет использоваться как имя персонажа. В противном случае, функция или вызываемый объект будут вызываться без аргументов перед каждой репликой, и возвращаемое значение будет использоваться как имя персонажа.
Управление взаимодействиями. Эти параметры управляют тем, будет ли отображаться диалог, произойдёт ли взаимодействие и в какой режим произойдёт переход при отображении.
- condition
Если задано, должна быть строка, содержащая Python-выражение. Если выражение ложно, диалог не происходит, как если бы инструкции say не было.
- interact
Если True (по умолчанию), взаимодействие происходит каждый раз, когда показывается диалог. Если False, взаимодействие не происходит, и на экран можно добавлять дополнительные элементы.
- advance
Если True (по умолчанию), игрок может кликать для продвижения по инструкции, и другие способы (такие как пропуск и автоматическое проматывание) также будут работать. Если False, игрок не сможет продвинуться дальше инструкции say, если не предоставлен альтернативный способ (например, гиперссылка jump или экран).
- callback
Функция, которая вызывается при возникновении событий, пока персонаж говорит. См. раздел Колбэки персонажа для получения дополнительной информации.
Индикатор продолжения. Индикатор продолжения (click-to-continue) отображается после того, как весь текст был показан, чтобы побудить пользователя к продолжению.
- ctc
Displayable, используемый в качестве индикатора продолжения, если не используется более специфичный индикатор.
- ctc_pause
Displayable, используемый в качестве индикатора продолжения, когда отображение текста приостановлено тегами {p} или {w}.
- ctc_timedpause
Displayable, используемый в качестве индикатора продолжения, когда отображение текста приостановлено тегами {p=} или {w=}. Если None, значение по умолчанию берётся из ctc_pause. Используйте
Null(), если вам нужен ctc_pause, но не ctc_timedpause.- ctc_position
Управляет расположением индикатора продолжения. Может быть:
- "nestled"
Индикатор отображается как часть показываемого текста, сразу после последнего символа.
- "nestled-close"
Аналогично
"nestled", но разрыв между текстом и индикатором CTC не допускается.- "fixed"
Если существует экран с именем "ctc", он показывается. В противном случае показывается displayable для CTC, и для его позиционирования используются свойства стиля position.
- "screen-variable"
Если задано, переменной с именем "ctc" присваивается displayable CTC, когда индикатор должен быть показан. Это можно использовать со следующим кодом на языке экранов:
default ctc = None showif ctc: add ctc
Экраны. Для отображения диалогов используется экран. Эти аргументы позволяют выбрать этот экран и передать ему параметры.
- screen
Имя экрана, который используется для отображения диалога.
- retain
Если не True, для каждой строки диалога генерируется неиспользуемый тег, и экраны показываются не временно (non-transiently). Вызовите
renpy.clear_retain()для удаления всех сохранённых экранов. Почти всегда используется с Речевые пузыри.
Именованные аргументы, начинающиеся с
show_, имеют отброшенный префикс и передаются на экран в качестве аргументов. Например, значениеshow_myflagстанет значением переменнойmyflagна экране. (Переменнаяmyflagпо умолчанию не используется, но может быть использована пользовательским экраном say.)Одна show переменная, по историческим причинам, обрабатывается самим Ren'Py:
- show_layer
Если задано, должна быть строка с именем слоя, на котором будет показан экран say.
Стилизация текста и окон. Именованные аргументы, начинающиеся с
who_,what_иwindow_, имеют отброшенный префикс и используются для стилизации имени персонажа, произносимого текста и окна, содержащего и то, и другое, соответственно.Например, если персонажу передан именованный аргумент
who_color="#c8ffc8", цвет имени персонажа изменится, в данном случае на зелёный.window_background="frame.png"устанавливает фон окна, содержащего диалог этого персонажа.Стиль, применяемый к имени персонажа, произносимому тексту и окну, также можно установить этим способом, используя аргументы
who_style,what_styleиwindow_styleсоответственно.Установка
config.character_id_prefixesпозволяет стилизовать и другие displayable. Например, при использовании стандартного GUI, стили с префиксомnamebox_используются для стилизации имени говорящего персонажа.
Say с атрибутами изображений
Когда персонаж определяется с ассоциированным тегом изображения, инструкция say, включающая этого персонажа, может иметь атрибуты изображения, размещённые между именем персонажа и второй строкой.
В этой форме, если изображение с указанным тегом отображается, Ren'Py выполнит команду show, включающую тег персонажа и атрибуты. Если изображение не отображается, Ren'Py сохранит атрибуты для использования боковыми изображениями (side images), но не будет показывать изображение.
Например:
define e = Character("Eileen", image="eileen")
label start:
show eileen concerned
e "I'm a little upset at you."
e happy "But it's just a passing thing."
эквивалентно:
define e = Character("Eileen")
label start:
show eileen concerned
e "I'm a little upset at you."
show eileen happy
e "But it's just a passing thing."
В приведённом выше примере concerned и happy заменяют друг друга.
Но можно вернуться к eileen без happy, не указывая атрибут concerned.
Имя атрибута с префиксом в виде знака минус ( - ) имеет такой эффект, так
же как и в инструкции show.
Например:
define e = Character("Eileen")
label start:
show eileen
e concerned "I'm a little upset at you."
e happy "That's funny."
e -happy "I'm not sure what to think now."
Когда в списке атрибутов присутствует @, любой элемент, расположенный после него, имеет только временный эффект и отменяется в конце строки диалога.
Например, следующий код эквивалентен предыдущему примеру:
define e = Character("Eileen", image="eileen")
label start:
show eileen concerned
e "I'm a little upset at you."
e @ happy "That's funny."
e "I'm not sure what to think now."
Одна строка может сочетать постоянные изменения, идущие до @, и временные, идущие после него.
e happy @ vhappy "Really! That changes everything."
Знак минус также можно использовать после знака @:
e @ right -concerned "My anger is temporarily suspended..."
e "HOWEVER !"
Чтобы переход происходил всякий раз, когда изображения изменяются таким образом,
установите config.say_attribute_transition в значение перехода.
Для большего контроля используйте config.say_attribute_transition_callback.
Примеры персонажей
Вот несколько примеров персонажей:
# Персонаж, диалог которого заключается в скобки.
define e = Character("Eileen", what_prefix='(', what_suffix=')')
# Персонаж, который берёт своё имя из переменной.
define p = Character("player_name", dynamic=True)
Особые персонажи
Несколько имён персонажей определены по умолчанию и используются автоматически в определённых ситуациях. Намеренное переопределение этих персонажей может изменить поведение Ren'Py, а случайное их использование может стать проблемой.
advСтандартный тип персонажа, используемый Character. Он настраивает персонажа таким образом, чтобы на экране одновременно отображалась одна строка.
nvlТип Character, который заставляет диалог отображаться в режиме NVL, с несколькими строками текста на экране одновременно.
narratorПерсонаж, используемый для отображения повествования в инструкциях say без указания имени персонажа.
name_onlyПерсонаж, используемый для диалогов, в которых имя персонажа задаётся строкой. Этот персонаж копируется в нового персонажа с заданным именем, а затем этот новый персонаж используется для отображения диалога.
centeredПерсонаж, который заставляет произносимый им текст отображаться по центру, в середине экрана, вне какого-либо окна.
vcenteredПерсонаж, который заставляет произносимый им текст отображаться по центру в виде вертикально ориентированного текста, в середине экрана, вне какого-либо окна.
extendПерсонаж, который заставляет последнего говорившего персонажа произнести строку диалога, состоящую из последней произнесённой строки диалога, «{fast}» и диалога, переданного extend. Это можно использовать для изменения экрана в ходе диалога.
Extend осведомлён о режиме NVL и корректно его обрабатывает. Extend не работает должным образом, если настройка языка изменяется между начальной инструкцией say и extend.
Например:
# Показать первую строку диалога, дождаться клика, сменить выражение и показать
# остальное.
show eileen concerned
e "Sometimes, I feel sad."
show eileen happy
extend " But I usually quickly get over it!"
# Похожий пример, но выражение меняется автоматически, когда первая строка заканчивает
# отображаться. Это имеет смысл, только если у пользователя скорость текста не установлена
# на максимум.
show eileen concerned
e "Sometimes, I feel sad.{nw}"
show eileen happy
extend " But I usually quickly get over it!"
Управление окном диалога
Ren'Py включает несколько инструкций, которые позволяют управлять окном диалога. Поскольку окно диалога всегда отображается во время диалога, эти инструкции контролируют наличие или отсутствие окна во время недиалоговых взаимодействий.
window showИнструкция window show заставляет окно отображаться. Она принимает в качестве необязательного аргумента переход, который используется для показа окна. Если переход опущен, используется
config.window_show_transition.window hideИнструкция window hide заставляет окно скрываться. Она принимает в качестве необязательного аргумента переход, который используется для скрытия окна. Если переход опущен, используется
config.window_hide_transition.window auto TrueЭто включает автоматическое управление окном. Окно отображается перед инструкциями, перечисленными в
config.window_auto_show— по умолчанию, это инструкции say. Окно скрывается перед инструкциями, перечисленными вconfig.window_auto_hide— по умолчанию, это инструкцииsceneиcall screen, а также инструкцииmenuбез заголовка.Учитываются только инструкции, а не их эквивалентные функции.
window auto FalseЭто отключает автоматическое управление окном. Окно не отображается и не скрывается автоматически.
Инструкция window auto использует config.window_show_transition
и config.window_hide_transition для отображения и скрытия окна,
соответственно. Действие window auto отменяется инструкциями window show и window hide.
Например:
window show # показывает окно с переходом по умолчанию, если он есть.
pause # окно отображается во время этой паузы.
window hide # скрывает окно.
pause # окно скрыто во время этой паузы.
window show dissolve # показывает окно с переходом dissolve.
pause # окно отображается во время этой паузы.
window hide dissolve # скрывает окно с переходом dissolve.
pause # окно скрыто во время этой паузы.
window auto True
"The window is automatically shown before this line of dialogue."
pause # окно отображается во время этой паузы.
scene bg washington # окно скрывается перед сменой сцены.
with dissolve
window show # Показывает окно раньше, чем оно обычно было бы показано.
show eileen
with dissolve
"Without window show, the window would have been shown here."
Управление окном диалога зависит от настройки «показывать
пустое окно» (show empty window). Если эта настройка отключена, приведённые
выше инструкции не имеют эффекта.
Say с аргументами
Дополнительные аргументы можно передать в инструкцию say, включив их в круглых скобках после инструкции. Например, можно написать:
e "Hello, world." (what_color="#8c8")
Аргументы инструкции say сначала обрабатываются функцией config.say_arguments_callback,
если она не None. Если какие-либо аргументы остаются, они передаются персонажу,
который обрабатывает их так, как если бы они были указаны при его определении.
Таким образом, в приведённом выше примере диалог отображается зелёным цветом.
Ключевое слово _with_none переопределит атрибут with_none персонажа.
Параметр interact — особый случай: если при определении Character было
передано значение False, передача interact=True не переопределит это,
что означает, что в этом случае взаимодействия не произойдёт.
Обратите внимание, что config.say_arguments_callback будет вызываться каждый раз
при выполнении инструкции say, а не только при передаче аргументов. Это может быть
полезно для реализации условных переопределений настроек персонажей.
Например:
init python:
def say_arguments_callback(char, *args, **kwargs):
if colorblind_mode:
kwargs["what_color"] = "#000"
return args, kwargs
define config.say_arguments_callback = say_arguments_callback
Режим монолога
В некоторых визуальных новеллах есть длинные повествования или несколько блоков диалога от одного и того же персонажа. В таких случаях многократный ввод имени персонажа и кавычек является излишним.
Для таких случаев Ren'Py поддерживает режим монолога. Когда диалог находится внутри строк в тройных кавычках, Ren'Py разбивает его на блоки по пустым строкам. Каждый блок затем используется для создания собственной инструкции say. Вот пример с тремя блоками повествования, за которыми следуют три строки диалога:
"""
This is the first line of narration. It's longer than the other two
lines, so it has to wrap.
This is the second line of narration.
This is the third line of narration.
"""
e """
This is the first line of dialogue. It's longer than the other two
lines, so it has to wrap.
This is the second line of dialogue.
This is the third line of dialogue.
"""
Хотя дополнительные конструкции, такие как аргументы или атрибуты, разрешены, они передаются каждой строке в монологе, что может быть менее полезным.
Если вы хотите убрать пробелы между блоками, напишите
rpy monologue single на верхнем уровне файла, перед первой
строкой монолога.
Если же вы хотите отключить это и чтобы все строки, написанные вами между
тройными кавычками, отображались как одно сообщение с сохранением переносов строк,
вы можете сделать это с помощью rpy monologue none.
Хранилище character
Основная статья: Другие именованные хранилища
Инструкция say будет искать в именованном хранилище character перед поиском
в хранилище по умолчанию. Если вы хотите иметь персонажа с таким же именем, как у
переменной в хранилище по умолчанию, его можно определить с помощью:
define character.e = Character("Eileen")
Затем этого персонажа можно использовать наряду с переменной в хранилище по умолчанию:
default e = 0
label start:
# Это всё ещё ужасное имя для переменной.
$ e = 100
e "Our current energy is [e] units."
Это особенно полезно для управления информацией о персонаже в пространстве имён без конфликта с инструкцией say:
define character.naomi = Character("Naomi Nagata", who_color="#8c8")
default naomi = PersonClass(engineering=5, max_g_force=.7) # может быть объектом...
define character.fred = Character("Fred Johnson", who_color="#72f")
default fred.money = 1000 # ...или выделенным именованным хранилищем
default fred.rank = "Colonel"
label traded:
fred "Here you go."
$ fred.money -= 50
$ naomi.money += 50
naomi "Thanks ! I knew you would value my class-[naomi.engineering] engineering skills."
Альтернативные представления
Руководство по NVL-режиму : режим, отображающий диалог на всём экране.
Речевые пузыри : режим, отображающий диалог в речевых пузырях, которые можно интерактивно позиционировать.
Смотрите также
Эквиваленты операторов : как использовать большинство описанных здесь функций в контексте Python, хотя и с некоторыми недостатками и ограничениями.
renpy.last_say() : предоставляет информацию о последней выполненной инструкции say.