Создание фонарика с помощью отображаемого объекта, определяемого разработчиком (Drawing a flashlight with a creator-defined displayable)

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

Это пример отображаемого объекта, определяемого разработчиком. Он скрывает всё на экране, за исключением небольшой области вокруг курсора, как при использовании фонарика в темной комнате. Этот код вдохновлён темой «Эффект фонарика?». Реализация очень похожа на пример из статьи «Отображаемые объекты, определяемые разработчиком», но детали разные. Следующий код:

init python:
    
    class Flashlight(renpy.Displayable):
        def __init__(self):
            super(Flashlight, self).__init__()
            
            # Это изображение должно быть в два раза больше ширины экрана и в два раза больше его высоты.
            self.child = Image("flashlight.png")

            # (-1, -1) это то, как система событий представляет 
            # "за пределами игрового окна".
            self.pos = (-1, -1)

        def render(self, width, height, st, at):
            render = renpy.Render(config.screen_width, config.screen_height)
            
            if self.pos == (-1, -1):
                # Если мы не знаем, где находится курсор, отобразите чистый черный цвет.
                render.canvas().rect("#000", (0, 0, config.screen_width, config.screen_height))
                return render

            # Визуализация изображения фонарика.
            child_render = renpy.render(self.child, width, height, st, at)

            # Нарисуйте изображение по центру курсора.
            flashlight_width, flashlight_height = child_render.get_size()
            x, y = self.pos
            x -= flashlight_width / 2
            y -= flashlight_height / 2
            render.blit(child_render, (x, y))
            return render

        def event(self, ev, x, y, st):
            # Перерисовка, если позиция изменилась.
            if self.pos != (x, y):
                renpy.redraw(self, 0)

            # Обновить сохраненную позицию.
            self.pos = (x, y)

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

Ожидается, что этот код сможет найти "flashlight.png": это изображение должно иметь ширину и высоту в два раза больше, чем у экрана, и оно должно быть черным с прозрачным отверстием в центре. Делать его вдвое больше экрана немного неэффективно, но это делает код намного проще. Я прикрепил тот, который использовал. Я нарисовал его в Paint.NET, используя инструмент градиента (радиальный режим, основной цвет прозрачный, дополнительный цвет черный). Вероятно, есть более эффективные способы, чтобы нарисовать изображение фонарика, если вы хотите, чтобы он выглядел как настоящий.

С точки зрения понимания кода, я думаю, что самым сложным является обработка случаев, когда мы вообще не хотим отображать фонарик (прозрачную дыру). Один случай - до вызова обратного вызова event(). Обратите внимание, что он не вызывается до первого вызова render(). Если вы пропишете вызов render.canvas().rect(), то уведите, что экран на мгновение мигает, прежде чем появляется фонарик. В другом случае курсор перемещается за пределы игрового окна. Обратный вызов event() представляет это с координатами (-1, -1).


Простой пример того, как его использовать:

screen flashlight_demo:
    textbutton "continue" xpos 300 ypos 300 action Return()
    add Flashlight()

label start:
    $ mouse_visible = False
    call screen flashlight_demo


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

Статья "Drawing a flashlight with a creator-defined displayable" на английском языке.


На главную страницу Книга рецептов Энциклопедии Ren'Py Форумы Lemma Soft Вернуться к началу статьи