Отображаемые объекты, определяемые разработчиком (Creator-Defined Displayables)

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

Самый сложный, но самый мощный способ настройки поведения Ren'Py – использование отображаемых объектов, определённых разработчиком. Такой объект может принимать произвольные события, генерируемые pygame. Он также может отображать другие отображаемые объекты и размещать их в произвольных местах на экране. Это позволяет создавать 2D мини-игры, которые нельзя выразить с помощью стандартных инструментов Ren'Py. Но также посмотрите раздел «Спрайты», который описывает высокоуровневый способ выполнения многих из тех же самых вещей.

Отображаемые объекты, определяемые разработчиком, полностью программируются на Python и мы рекомендуем вам иметь достаточно высокий навык в объектно-ориентированном программировании на Python, прежде чем приступить к его созданию.

Пример (Example)[править | править код]

Вот пример отображаемого объекта, определяемого разработчиком. В данном коде дочерний элемент отображаемого объекта с альфа-каналом проявляется при наведении указателя мыши (степень отображения зависит от расстояния указателя мыши к центру дочернего элемента).

init python:

    import math

    class Appearing(renpy.Displayable):

        def __init__(self, child, opaque_distance, transparent_distance, **kwargs):

            # Передаёт дополнительные свойства конструктору renpy.Displayable.
            super(Appearing, self).__init__(**kwargs)

            # Дочерний элемент.
            self.child = renpy.displayable(child)

            # Расстояние, на котором дочерний элемент станет полностью непрозрачным, и
            # где он станет полностью прозрачным. Первое должно быть меньше,
            # чем последнее.
            self.opaque_distance = opaque_distance
            self.transparent_distance = transparent_distance

            # Альфа-канал дочернего элемента.
            self.alpha = 0.0

            # Ширина и высота отображаемого объекта и его дочернего элемента.
            self.width = 0
            self.height = 0

        def render(self, width, height, st, at):

            # Создаёт преобразование, которое может настроить альфа-канал
            # дочернего элемента.
            t = Transform(child=self.child, alpha=self.alpha)

            # Создаёт рендер из дочернего элемента.
            child_render = renpy.render(t, width, height, st, at)

            # Определяет размер дочернего элемента.
            self.width, self.height = child_render.get_size()

            # Создаёт рендер, который вернётся.
            render = renpy.Render(self.width, self.height)

            # Переносит фрагмент растрового изображения (рисует) рендер дочернего элемента на наш рендер.
            render.blit(child_render, (0, 0))

            # Возвращает рендер.
            return render

        def event(self, ev, x, y, st):

            # Вычисляет расстояние между центром этого отображаемого объекта и
            # указателя мыши. Указатель мыши поставляется в формате x и y,
            # относительно верхнего левого угла отображаемого объекта.
            distance = math.hypot(x - (self.width / 2), y - (self.height / 2))

            # Основываясь на расстоянии, вычисляет alpha.
            if distance <= self.opaque_distance:
                alpha = 1.0
            elif distance >= self.transparent_distance:
                alpha = 0.0
            else:
                alpha = 1.0 - 1.0 * (distance - self.opaque_distance) / (self.transparent_distance - self.opaque_distance)

            # Если alpha изменился, вызовите событие перерисовки.
            if alpha != self.alpha:
                self.alpha = alpha
                renpy.redraw(self, 0)

            # Передайте это событие своему дочернему элементу
            return self.child.event(ev, x, y, st)

        def visit(self):
            return [ self.child ]

Чтобы использовать отображаемый объект, определяемый разработчиком, создайте его экземпляр и добавьте его на экран.

screen alpha_magic:
    add Appearing("logo.png", 100, 200):
        xalign 0.5
        yalign 0.5

label start:
    show screen alpha_magic

    "Вы можете найти логотип?"

    return

Класс renpy.Displayable (renpy.Displayable)[править | править код]

Отображаемый объект, определяемый разработчиком, создаётся путем создания подкласса класса renpy.Displayable. Данный объект должен переопределить метод рендеринга, а также может переопределить другие методы.

Отображаемый объект должен иметь возможность выбора, что означает, что он не может содержать ссылки на объекты, которые невозможно выбрать. В частности, объекты Render не могут храниться в отображаемом объекте, определяемом разработчиком.

Поскольку мы ожидаем, что вы переопределите методы отображаемого класса, мы представим их с параметром self.


class renpy.Displayable

Базовый класс для отображаемых объектов, определяемых разработчиком.
__init__(**properties)
Подкласс может переопределить конструктор, возможно добавив новые параметры. Если это так, он должен передать все неизвестные именованные аргументы в конструктор renpy.Displayable с помощью вызова:
super(MyDisplayable, self).__init__(**properties)


render(self, width, height, st, at)
Подклассы должны переопределить это, чтобы вернуть объект renpy.Render. Объект рендеринга определяет, что именно отображается на экране.
width, height
Величина доступного свободного пространства для этого отображаемого объекта, в пикселях.
st
Число с плавающей точкой, отображаемое в секундах. Показанное время начинается, когда этот отображаемый объект впервые отображается на экране.
at
Число с плавающей точкой, время анимации, в секундах. Время анимации начинается, когда изображение с тем же тегом было показано, не будучи скрытым. Когда отображаемый объект выводится без тега, он совпадает с показанным интервалом времени).
Метод рендеринга вызывается при первом выведении отображаемого объекта. Его можно вызвать снова, если для этого объекта вызывается renpy.redraw().


event(self, ev, x, y, st)
Метод event вызывается для передачи события pygame в отображаемый объект, определяемый разработчиком. Если данный метод возвращает значение, отличное от None, то это значение возвращается как результат взаимодействия.
Метод event существует в других отображаемых объектах, что позволяет отображаемому объекты, отображаемому разработчиком, передавать событие.
ev
Объект события.
x, y
Координаты x и y события относительно верхнего левого угла отображаемого объекта. Их следует использовать в предпочтении к информации о местоположении, найденной в объектах события pygame.
st
Число с плавающей точкой, в секундах.
Событие генерируется в начале каждого взаимодействия, и renpy.timeout() можно использовать для того, чтобы вызвать другое событие.


per_interact(self)
Этот метод вызывается в начале каждого взаимодействия. Он может использоваться для запуска перерисовки и, вероятно, должен использоваться для запуска перерисовки, если объект участвует в откате.


visit(self)
Если у отображаемого объекта есть дочерние отображаемые объекты, этот метод должен быть переопределен, чтобы вернуть список отображаемых объектов. Это гарантирует, что вызываются методы per_interact этих отображаемых объектов, а также позволяет прогнозировать изображения, используемые этими отображаемыми объектами.

Класс renpy.Render (renpy.Render)[править | править код]

Отображаемые объекты, определяемые разработчиком, работают с объектами renpy.Render. Объекты рендеринга возвращаются путём вызова функции renpy.render() для отображаемого объекта. Отображаемый объект, определяемый разработчиком, должен создавать объект Render, вызывая renpy.Render из его метода рендеринга.

Поскольку объект рендеринга не предназначен для создания подклассов, мы опускаем неявный параметр self.


class renpy.Render(width, height)

Создаёт новый объект Render.
width, height
Ширина и высота объекта рендеринга в пикселях.


blit(source, pos, main=True)
Рисует другой объект рендеринга в этот объект рендеринга.
source
Объект рендеринга для рисования.
pos
Место для рисования. Это кортеж (x, y) с координатами в пикселях относительно левого верхнего угла целевого рендера.
main
Параметр только для ключевых слов. Если принимает значение True, источник будет отображаться в инспекторе стилей.


place(d, x=0, y=0, width=None, height=None, st=None, at=None, render=None, main=True)
Отображает d и помещает его в прямоугольник, определенный x, y, width и height, используя стандартный алгоритм размещения Ren'Py.
x, y, width, height
Прямоугольник для размещения внутри. Если width или height, когда принимают значение None, являются шириной и высотой этого рендера, соответственно.
st, at
Время, переданное объекту Render. Если принимает значение None, по умолчанию используется время, переданное методу рендеринга, вызывающему этот метод.
render
Если принимает значение не None, это используется вместо рендеринга d.
main
В отношении .blit().


canvas()
Возвращает объект canvas. У объекта canvas есть методы, соответствующие функциям pygame.draw, при этом первый параметр (surface) опущен.
Объекты canvas также имеют метод get_surface() который возвращает pygame Surface, лежащий в основе canvas.


get_size()
Возвращает кортеж (ширина, высота), задающий размер этого рендера.


subsurface(rect)
Возвращает рендер, состоящий из прямоугольника, вырезанного из этого рендера.
rect
Кортеж (x, y, ширина, высота).


zoom(xzoom, yzoom)
Устанавливает уровень масштабирования дочерних элементов этого отображаемого объекта по горизонтальной и вертикальной осям. Увеличиваются только дочерние элементы отображаемого объекта – ширина, высота и координаты blit не масштабируются.

Вспомогательные функции (Utility Functions)[править | править код]

Эти функции управляют процессом рендеринга.


renpy.displayable(d, scope=None)

Занимает d, который может быть отображаемым объектом или строкой. Если эта строка, она преобразует эту строку в отображаемый объект, используя обычные правила.


renpy.end_interaction(value)

Если value принимает значение не None, немедленно завершает текущее взаимодействие, в результате чего взаимодействие возвращает value. Если value принимает значение None, ничего не делает.
Это можно вызвать изнутри методов рендеринга и событий отображаемого объекта, определяемого разработчиком.


renpy.load_image(im)

Загружает манипулятор изображений im, используя кэш изображений, и возвращает рендер.


renpy.load_surface(im)

Загружает манипулятор изображений im, используя кэш изображений, и возвращает Surface pygame.


renpy.map_event(ev, keysym)

Возвращает значение True, если событие Pygame ev соответствует keysym.
keysym
Один из:


renpy.render(d, width, height, st, at)

Приводит к отображению отображаемого объекта и возвращению объекта renpy.Render.
d
Отображаемый объект для визуализации.
width, height
Ширина и высота, доступные для отображаемого объекта для рендеринга.
st, at
Показанные и анимационные временные рамки.
Рендеры, возвращаемые этим объектом, могут кэшироваться, и их не следует изменять после получения. Это гарантирует, что будет вызван метод события отображаемого объекта, определяемого разработчиком.


renpy.timeout(seconds)

Вызывает событие, которое должно быть сгенерировано до истечения seconds.


renpy.redraw(d, when)

Вызывает перерисовку отображаемого d после истечения нескольких when секунд.

Источник[править | править код]

Статья "Creator-Defined Displayables" на английском языке.


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