Отображение изображений
Определяющим аспектом визуальной новеллы, дающим название жанру, является визуальная составляющая. Ren'Py содержит четыре инструкции, которые управляют отображением изображений, и модель, которая определяет порядок их отображения. Это делает удобным отображение изображений в манере, подходящей для использования в визуальных новеллах и других сюжетных играх.
Четыре инструкции, которые работают с изображениями:
image- определяет новое изображение.show- показывает изображение на слое.scene- очищает слой и опционально показывает изображение на этом слое.hide- убирает изображение со слоя.
Поскольку резкие смены изображений могут дезориентировать пользователя, в Ren'Py
есть инструкция with, которая позволяет применять эффекты
при смене сцены.
Большинство (если не все) инструкций, перечисленных на этой странице, проверяются Lint, в отличие от их эквивалентов на Python.
Основные понятия
Изображение (Image)
Изображение — это то, что можно показать на экране с помощью инструкции show. Изображение состоит из имени и отображаемого объекта (displayable). Когда изображение показывается на слое, связанный с ним отображаемый объект отображается на этом слое.
Имя изображения состоит из одного или нескольких имён, разделённых пробелами. Первый компонент имени изображения называется тегом изображения. Второй и последующие компоненты имени — это атрибуты изображения.
Например, возьмём имя изображения mary beach night happy. Тег изображения —
mary, а атрибуты — beach, night и happy.
Отображаемый объект — это то, что можно показать на экране. Наиболее
распространённым объектом является статичное изображение, которое можно задать,
указав имя файла изображения в виде строки. В приведённом выше примере мы
могли бы использовать mary_beach_night_happy.png в качестве имени файла.
Однако изображение может ссылаться на любой отображаемый объект, который
поддерживает Ren'Py, а не только на статичные изображения. Таким
образом, те же инструкции, которые используются для отображения изображений,
могут также использоваться для анимаций, сплошных цветов и других типов
отображаемых объектов.
Слой (Layer)
Слой — это список отображаемых объектов, которые показываются на экране. Ren'Py
поддерживает несколько слоёв, включая слои, определённые пользователем. Порядок
слоёв в игре фиксирован (управляется переменной config.layers), в то время
как порядок отображаемых объектов внутри слоя контролируется порядком вызова
инструкций scene и show, а также свойствами, заданными этим инструкциям.
В Ren'Py по умолчанию определены следующие слои:
- master
Это слой по умолчанию, который используется инструкциями scene, show и hide. Обычно он используется для фонов и спрайтов персонажей.
- transient
Слой по умолчанию, используемый UI-функциями. Этот слой очищается в конце каждого взаимодействия.
- screens
Этот слой используется системой экранов.
- overlay
Слой по умолчанию, используемый, когда UI-функция вызывается изнутри функции оверлея. Этот слой очищается при перезапуске взаимодействия.
Дополнительные слои могут быть определены вызовом renpy.add_layer() и
использованием различных конфигурационных переменных, связанных со слоями.
Используя инструкцию camera, к слою можно применить одну или
несколько трансформаций.
Определение изображений
Существует два способа определения изображений. Вы можете либо поместить файл изображения в папку image, либо определить изображение с помощью инструкции image. Первый способ прост, так как он заключается в размещении правильно названных файлов в каталоге, в то время как второй позволяет лучше контролировать определение изображения и использовать изображения, которые не являются файлами.
Изображения, определённые с помощью инструкции image, имеют приоритет над теми, что определены через каталог images.
Каталог изображений (Images Directory)
Каталог изображений называется «images» и располагается в каталоге игры. Когда файл с расширением .jpg, .jpeg, .png, .webp, .avif или .svg помещается в этот каталог, расширение удаляется, остальная часть имени файла приводится к нижнему регистру, и полученное имя файла используется в качестве имени изображения, если изображение с таким именем не было определено ранее.
Этот процесс происходит во всех подкаталогах каталога images. Например,
все эти файлы определят изображение eileen happy:
game/images/eileen happy.png
game/images/Eileen Happy.jpg
game/images/eileen/eileen happy.png
Когда указано имя файла изображения и оно не найдено, производится поиск в каталоге images.
Каталог изображений можно настроить с помощью config.image_directories и
config.image_extensions.
Оверсемплинг (Oversampling)
По умолчанию размер изображения в пикселях определяет размер, который оно займёт
при отображении. Например, если изображение имеет размер 1920x1080 пикселей, а
игра настроена на работу с разрешением 1920x1080 с помощью gui.init(), то
изображение заполнит весь экран.
Когда включён оверсемплинг, размер, с которым отображается изображение, меньше, чем можно было бы предположить по его размеру в пикселях. Например, если изображение имеет размер 3480x2160 и оверсемплинг равен 2, то каждая ось будет уменьшена вдвое, и изображение заполнит то же самое окно 1920x1080.
Это полезно, когда изображение может быть увеличено, и требуется дополнительная
детализация. Оверсемплинг также полезен в сочетании с config.physical_width
и config.physical_height, чтобы позволить переделать игру с графикой
более высокого разрешения.
Оверсемплинг автоматически включается, если имя файла изображения заканчивается на
'@', за которым следует число, перед расширением. Например, eileen happy@2.png
имеет 2x оверсемплинг, а eileen happy@3.png — 3x оверсемплинг. Оверсемплинг
также можно включить, передав аргумент oversample функции Image().
Каталог также может указывать, насколько увеличивать оверсемплинг изображений внутри него.
Например, images/@2/eileen happy.png будет иметь 2x оверсемплинг.
Если к изображению не применён оверсемплинг, Ren'Py попытается автоматически найти
изображения с оверсемплингом для использования. Например, если игра масштабируется
более чем в 1x, но не более чем в 2x, Ren'Py при загрузке eileen happy.png
будет искать eileen happy@2.png и использовать его, если он существует. Если
масштабирование больше 2x, Ren'Py будет искать eileen happy @4.png, eileen happy@3.png
и eileen happy@2.png и использует первый найденный, или eileen happy.png, если
ни один из них не существует.
Инструкция image
Инструкция image используется для определения изображения. Инструкция image
состоит из одной логической строки, начинающейся с ключевого слова image,
за которым следует имя изображения, знак равенства = и
отображаемый объект. Например:
image eileen happy = "eileen_happy.png"
image black = "#000"
image bg tiled = Tile("tile.jpg")
image eileen happy question = VBox(
"question.png",
"eileen_happy.png",
)
Когда файл изображения находится не непосредственно в каталоге игры, вам
нужно указать подкаталоги. Например, если изображение находится по пути
game/eileen/happy.png, то вы можете написать:
image eileen happy = "eileen/happy.png"
Инструкция image выполняется во время инициализации, до того, как будут
показаны меню или запустится метка start. Если инструкции image не находятся
внутри блока init, они выполняются так, как если бы они были помещены
внутрь блока init с приоритетом 500.
Смотрите также ATL-вариант инструкции image.
Инструкция show
Инструкция show используется для отображения изображения на слое. Инструкция
show состоит из одной логической строки, начинающейся с ключевого
слова show, за которым следует имя изображения, а затем ноль или
более свойств.
Если инструкции show передано точное имя существующего изображения, то именно это изображение и будет показано. В противном случае Ren'Py попытается найти уникальное изображение, которое:
Имеет тот же тег, что и указанный в инструкции show.
Имеет все атрибуты, указанные в инструкции show.
Если изображение с таким же тегом уже отображается, имеет наибольшее количество общих атрибутов с этим изображением.
Если уникальное изображение найти не удаётся, возникает исключение.
Если изображение с тем же тегом уже отображается на слое,
новое изображение заменяет его. В противном случае изображение помещается
поверх всех других изображений на слое. (То есть, ближе к пользователю.)
Этот порядок может быть изменён свойствами zorder и behind.
Инструкция show не вызывает взаимодействия. Чтобы изображение действительно было показано пользователю, должна быть выполнена инструкция, вызывающая взаимодействие (например, say, menu, pause или with).
Инструкция show принимает следующие свойства:
asСвойство
asпринимает имя. Это имя используется вместо тега изображения при его отображении. Это позволяет одному и тому же изображению находиться на экране дважды.atСвойство
atпринимает одно или несколько разделённых запятыми простых выражений. Каждое выражение должно вычисляться в трансформацию. Трансформации применяются к изображению в порядке слева направо.Если предложение at не задано, Ren'Py сохранит любую существующую трансформацию, которая была применена к изображению, если они были созданы с помощью ATL или
Transform. Если трансформация не указана, изображение будет отображено с использованием трансформацииdefault.См. раздел о замене трансформаций, чтобы узнать, как замена трансформаций, связанных с тегом, может изменить свойства трансформации.
behindПринимает разделённый запятыми список из одного или нескольких имён. Каждое имя рассматривается как тег изображения. Изображение показывается позади всех изображений с указанными тегами, которые в данный момент отображаются.
onlayerПринимает имя. Показывает изображение на указанном слое.
zorderПринимает целое число. Это число определяет относительный порядок изображений на слое, где большие числа означают, что изображение ближе к пользователю. Обычно в играх на Ren'Py это не используется, но может быть полезно при портировании визуальных новелл с других движков. Это также может быть полезно для отображения изображения, которое будет находиться поверх любого другого изображения без zorder, отображённого позже, без необходимости размещать его на другом слое.
Предположим, у нас определены следующие изображения:
image mary night happy = "mary_night_happy.png"
image mary night sad = "mary_night_sad.png"
image moon = "moon.png"
Вот несколько примеров инструкций show:
# Базовое использование show.
show mary night sad
# Поскольку 'mary night sad' уже отображается, следующая инструкция
# эквивалентна:
# show mary night happy
show mary happy
# Показать изображение в правой части экрана.
show mary night happy at right
# Показать одно и то же изображение дважды.
show mary night sad as mary2 at left
# Показать изображение позади другого.
show moon behind mary, mary2
# Показать изображение на пользовательском слое.
show moon onlayer user_layer
Управление атрибутами
Как показано выше, атрибуты можно задавать, добавлять и заменять.
Их также можно удалять с помощью знака минус:
# показать Сьюзен в нейтральном настроении
show susan
# показать Сьюзен в счастливом настроении
show susan happy
# снова показать Сьюзен в нейтральном настроении
show susan -happy
Show с выражением (show expression)
Вариант инструкции show заменяет имя изображения ключевым словом
expression, за которым следует простое выражение. Выражение
должно вычисляться в отображаемый объект, и этот объект
отображается на слое. Чтобы скрыть этот отображаемый объект, необходимо
задать ему тег с помощью предложения as.
Например:
show expression "moon.png" as moon
Show Layer
Инструкция show layer рассматривается вместе с инструкцией
camera ниже.
Инструкция scene
Инструкция scene удаляет все отображаемые объекты со слоя, а затем
показывает изображение на этом слое. Она состоит из ключевого слова
scene, за которым следует имя изображения, а затем ноль или более
свойств. Изображение показывается так же, как и в инструкции show, и
инструкция scene принимает те же свойства, что и инструкция show.
Инструкция scene часто используется для показа изображения на фоновом слое. Например:
scene bg beach
Scene с выражением (Scene Expression). Как и инструкция show, инструкция scene может принимать выражения вместо имён изображений.
Очистка слоя. Если имя изображения полностью опущено, инструкция scene очищает все отображаемые объекты со слоя, не показывая нового отображаемого объекта.
Инструкция hide
Инструкция hide удаляет изображение со слоя. Она состоит из
ключевого слова hide, за которым следует имя изображения и необязательное
свойство. Инструкция hide берёт тег изображения из имени изображения
и затем скрывает любое изображение на слое с этим тегом.
Инструкции hide редко бывают необходимы. Если спрайт представляет персонажа, то инструкция hide нужна только тогда, когда персонаж покидает сцену. Когда персонаж меняет свою эмоцию, предпочтительнее использовать инструкцию show, так как show автоматически заменит изображение с тем же тегом.
Инструкция hide принимает следующее свойство:
onlayerПринимает имя. Скрывает изображение с указанного слоя.
Например:
e "Я ухожу отсюда."
hide eileen
Никогда не следует писать так:
hide eileen
show eileen happy
Вместо этого просто пишите:
show eileen happy
Инструкция with
Инструкция with используется для применения эффекта перехода при
смене сцены, делая появление и исчезновение изображений менее резким. Инструкция
with состоит из ключевого слова with, за которым следует простое
выражение, которое вычисляется либо в объект перехода, либо в специальное
значение None.
Эффект перехода применяется между содержимым экрана в конце предыдущего взаимодействия (с временными (transient) экранами и отображаемыми объектами скрытыми) и текущим содержимым сцены, после выполнения инструкций show и hide.
Инструкция with вызывает взаимодействие. Длительность этого взаимодействия контролируется пользователем, и пользователь может прервать его досрочно.
Полный список переходов, которые можно использовать, см. в главе о переходах.
Пример инструкции with:
show bg washington
with dissolve
show eileen happy at left
show lucy mad at right
with dissolve
Это вызовет два перехода. Первая инструкция with использует
переход dissolve для смены экрана с того, что было показано
ранее, на фон Вашингтона. (Переход dissolve по умолчанию
определён как растворение длительностью 0,5 секунды.)
Второй переход происходит после показа изображений Айлин и Люси. Он вызывает растворение от сцены, состоящей только из фона, к сцене, состоящей из всех трёх изображений — в результате два новых изображения появляются, как бы растворяясь одновременно.
With None
В приведённом выше примере происходит два растворения. Но что, если мы хотели, чтобы фон появился мгновенно, а затем последовало растворение двух персонажей? Простое опускание первой инструкции with привело бы к тому, что все три изображения растворились бы — нам нужен способ сказать, что первое должно появиться мгновенно.
Инструкция with изменяет своё поведение, когда ей передаётся специальное
значение None. Инструкция with None вызывает сокращённое
взаимодействие, не меняя того, что видит пользователь. Когда
произойдёт следующий переход, он начнётся со сцены в том виде, в
котором она была в конце этого сокращённого взаимодействия.
Например, в:
show bg washington
with None
show eileen happy at left
show lucy mad at right
with dissolve
Произойдёт только один переход — от фона Вашингтона к сцене, состоящей из всех трёх изображений.
Предложение With в инструкциях Scene, Show и Hide
Инструкции show, scene и hide могут принимать необязательное
предложение with, которое позволяет комбинировать переход с
показом или скрытием изображения. Это предложение следует за
инструкциями в конце той же логической строки. Оно начинается
с ключевого слова with, за которым следует простое выражение.
Предложение with эквивалентно тому, чтобы перед строкой поставить
инструкцию with None, а после неё — инструкцию with,
содержащую текст предложения with. Например:
show eileen happy at left with dissolve
show lucy mad at right with dissolve
эквивалентно:
with None
show eileen happy at left
with dissolve
with None
show lucy mad at right
with dissolve
Обратите внимание, что хотя это также применимо к инструкциям Show Screen и Hide Screen, инструкция Call Screen работает иначе.
Инструкции Camera и Show Layer
Инструкция camera позволяет применить трансформацию или ATL-трансформацию ко
всему слою (например, «master»), используя синтаксис вроде:
camera at flip
или:
camera:
xalign 0.5 yalign 0.5 rotate 180
Чтобы прекратить применение трансформаций к слою, используйте:
camera
Инструкция camera принимает необязательное имя слоя между camera и
at или :.
camera mylayer at flip
Инструкция show layer является более старой версией camera с некоторыми
различиями, которая всё ещё может быть полезна.
show layer master:
blur 10
Различия заключаются в следующем:
Трансформации, применённые с помощью
show layer, очищаются при следующей инструкцииscene, в то время как трансформацииcameraдействуют до тех пор, пока их явно не очистят.show layerтребует имя слоя, в то время какcameraпо умолчанию использует слой master.
Скрытие и показ окна
Инструкция window используется для управления показом окна диалога, когда
персонаж не говорит (например, во время переходов и пауз). Инструкция
window show заставляет окно показываться, а window hide — скрывает его.
Если указан необязательный переход, он используется для показа и скрытия окна.
Если он не указан, используются значения по умолчанию
config.window_show_transition и config.window_hide_transition.
Передача None в качестве перехода отменяет его выполнение.
Само окно отображается вызовом config.empty_window. По умолчанию это
равносильно тому, что рассказчик говорит пустую строку.
show bg washington
show eileen happy
with dissolve
window show dissolve
"Я могу говорить..."
show eileen happy at right
with move
"...и двигаться, при этом окно остаётся видимым."
window hide dissolve
Функции изображений
- renpy.add_layer(layer, above=None, below=None, menu_clear=True, sticky=None)
Добавляет новый слой на экран. Если слой уже существует, эта функция ничего не делает.
Должен быть указан один из параметров: behind или above.
- layer
Строка, задающая имя нового добавляемого слоя.
- above
Если не None, строка, задающая имя слоя, над которым будет размещён новый слой.
- below
Если не None, строка, задающая имя слоя, под которым будет размещён новый слой.
- menu_clear
Если истинно, этот слой будет очищаться при входе в контекст игрового меню и восстанавливаться при выходе из него.
- sticky
Если истинно, любые теги, добавленные к этому слою, будут использовать его в качестве своего слоя по умолчанию, пока они не будут скрыты. Если None, этот слой будет «липким» (sticky), только если уже существуют другие «липкие» слои.
- renpy.can_show(name, layer=None, tag=None)
Определяет, можно ли использовать name для показа изображения. Эта функция интерпретирует name как тег и атрибуты. Это сочетается с атрибутами текущего показываемого изображения с тегом tag на слое layer в попытке определить уникальное изображение для показа. Если уникальное изображение может быть показано, возвращает имя этого изображения в виде кортежа. В противном случае, возвращает None.
- tag
Тег изображения для получения атрибутов. Если не задан, по умолчанию используется первый компонент name.
- layer
Слой для проверки. Если None, используется слой по умолчанию для tag.
- renpy.change_zorder(layer, tag, zorder)
Изменяет zorder тега tag на слое layer на zorder.
- renpy.check_image_attributes(tag, attributes)
Проверяет, существует ли уникальное изображение с заданным тегом и атрибутами. Если да, возвращает атрибуты по порядку. В противном случае, возвращает None.
- renpy.clear_attributes(tag, layer=None)
Очищает все атрибуты изображения для тега tag. Если у тега не было связанных атрибутов изображения, эта функция ничего не делает.
- layer
Слой для проверки. Если None, используется слой по умолчанию для tag.
- renpy.copy_images(old, new)
Копирует изображения, начинающиеся с одного префикса, в изображения, начинающиеся с другого. Например:
renpy.copy_images("eileen", "eileen2")
создаст изображение, начинающееся с "eileen2", для каждого изображения, начинающегося с "eileen". Если существует "eileen happy", будет создано "eileen2 happy".
- old
Строка с пробелами, задающая компоненты имени старого изображения.
- new
Строка с пробелами, задающая компоненты имени нового изображения.
Эта функция может быть вызвана только из блока init. Вызов этой функции после запуска игры является ошибкой. Поскольку инструкция
imageвыполняется с приоритетом init 500, эту функцию следует вызывать с приоритетом init 501 или выше.
- renpy.flush_cache_file(fn)
Эта функция сбрасывает все записи кэша изображений, которые относятся к файлу fn. Это можно вызывать, когда файл изображения на диске изменяется, чтобы заставить Ren'Py использовать новую версию.
- renpy.get_attributes(tag, layer=None, if_hidden=None)
Возвращает кортеж с атрибутами изображения для тега tag. Если с тегом изображения не были связаны какие-либо атрибуты с момента последнего скрытия, возвращает if_hidden.
- layer
Слой для проверки. Если None, используется слой по умолчанию для tag.
- renpy.get_available_image_tags()
Возвращает список тегов изображений, которые были определены.
Возвращает множество тегов изображений на слое layer, которые в данный момент скрыты, но с которыми все ещё связана информация об атрибутах.
- renpy.get_image_bounds(tag, width=None, height=None, layer=None)
Если изображение с тегом tag существует на слое layer, возвращает ограничивающую рамку (bounding box) этого изображения. Возвращает None, если изображение не найдено.
Ограничивающая рамка — это кортеж (x, y, width, height). Компоненты кортежа выражены в пикселях и могут быть числами с плавающей точкой.
- width, height
Ширина и высота области, содержащей изображение. Если None, по умолчанию используются ширина и высота экрана соответственно.
- layer
Если None, используется слой по умолчанию для tag.
- renpy.get_ordered_image_attributes(tag, attributes=(), sort=None)
Возвращает список атрибутов изображения, упорядоченный таким образом, чтобы его было удобно представить пользователю.
- attributes
Если указаны, рассматриваются только атрибуты, совместимые с данными атрибутами. (Совместимые означает, что атрибуты могут находиться в одном изображении одновременно.)
- sort
Если не None, возвращаемый список атрибутов сортируется. Это одноаргументная функция, которую следует использовать для разрешения неоднозначностей — смотрите это руководство для получения дополнительной информации.
- renpy.get_placement(d)
Эта функция получает размещение displayable d. Надёжность этой информации не гарантируется, так как она может измениться при отрисовке displayable и может отсутствовать до его первой отрисовки.
Функция возвращает объект со следующими полями, каждое из которых соответствует свойству стиля:
pos
xpos
ypos
anchor
xanchor
yanchor
offset
xoffset
yoffset
subpixel
- renpy.get_registered_image(name)
Если изображение с таким же именем было зарегистрировано, возвращает его. В противном случае, возвращает None.
- renpy.get_say_image_tag()
Возвращает тег, соответствующий говорящему в данный момент персонажу (аргумент image, переданный этому персонажу). Возвращает None, если персонаж не говорит или у текущего говорящего персонажа нет соответствующего тега изображения.
- renpy.get_showing_tags(layer='master', sort=False)
Возвращает множество тегов изображений, которые в данный момент отображаются на слое layer. Если sort истинно, возвращает список тегов от заднего плана к переднему.
- renpy.get_zorder_list(layer)
Возвращает список пар (tag, zorder) для слоя layer.
- renpy.has_image(name, exact=False)
Возвращает true, если изображение с именем name существует, и false, если такого изображения нет.
- name
Либо строка, задающая имя изображения, либо кортеж строк, задающий компоненты имени.
- exact
Возвращает true тогда и только тогда, когда существует изображение с точным именем — параметризованные совпадения не учитываются.
- renpy.list_images()
Возвращает список изображений, которые были добавлены в Ren'Py, в виде списка строк с пробелами между компонентами имени.
- renpy.mark_image_seen(name)
Помечает указанное изображение так, как будто оно уже было отображено в системе текущего пользователя.
- renpy.mark_image_unseen(name)
Помечает указанное изображение так, как будто оно ещё не было отображено в системе текущего пользователя.
- renpy.seen_image(name)
Возвращает True, если указанное изображение было увидено хотя бы один раз в системе пользователя. Изображение считается увиденным, если оно было отображено с помощью инструкции show, scene или функции
renpy.show(). (Обратите внимание, что бывают случаи, когда пользователь на самом деле не увидит изображение, например, при вызове show сразу после которого следует hide.)
- renpy.showing(name, layer=None)
Возвращает true, если изображение с тем же тегом, что и name, отображается на слое layer.
- image
Может быть строкой, задающей имя изображения, или кортежем, задающим каждый компонент имени изображения. Также это может быть строка, задающая только тег изображения.
- layer
Слой для проверки. Если None, используется слой по умолчанию для tag.
- renpy.start_predict(*args)
Эта функция принимает один или несколько displayable-объектов в качестве аргументов. Она заставляет Ren'Py предзагружать эти displayable-объекты во время каждого интерактива, пока они не будут удалены функцией
renpy.stop_predict().Если имя displayable-объекта является строкой, содержащей один или несколько символов *, звёздочки используются как шаблон-маска. Если в строке есть хотя бы одна ., шаблон сопоставляется с именами файлов, в противном случае — с именами изображений.
Например:
$ renpy.start_predict("eileen *")
начинает предзагрузку всех изображений с именем eileen, в то время как:
$ renpy.start_predict("images/concert*.*")
соответствует всем файлам, начинающимся с concert в каталоге images.
Предзагрузка будет происходить во время обычного игрового процесса. Чтобы дождаться завершения предзагрузки, используйте аргумент predict для функции
renpy.pause().
- renpy.stop_predict(*args)
Эта функция принимает один или несколько displayable-объектов в качестве аргументов. Она заставляет Ren'Py прекратить предзагрузку этих displayable-объектов во время каждого интерактива.
Шаблоны-маски могут использоваться так же, как описано в
renpy.start_predict().
Смотрите также
Эквиваленты операторов : как использовать большинство описанных здесь возможностей в контексте Python.
Displayables : другие объекты для отображения, более разнообразные, чем простые изображения.