Page 1 of 1

X-ray effect: Creator-Defined Displayable

Posted: Wed May 12, 2021 5:24 pm
by Moshibit
This turns the mouse pointer into a device to see inside things.

You need two images, the outside of an object and the inside.

The following script is a slight modification of the Creator-Defined Displayables example from the documentation, it originated while I was studying how to create displyables:

Code: Select all

init python:

    import math

    class XRay(renpy.Displayable):

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

            # Pass additional properties on to the renpy.Displayable
            # constructor.
            super(XRay, self).__init__(**kwargs)

            # The childs.
            self.child = renpy.displayable(child) # Top
            self.child2 = renpy.displayable(child2) # bottom

            # The distance at which the child will become fully opaque, and
            # where it will become fully transparent. The former must be less
            # than the latter.
            self.opaque_distance = opaque_distance
            self.transparent_distance = transparent_distance

            # The alpha channel of the child.
            self.alpha = 0.0

            # The width and height of us, and our child.
            self.width = 0
            self.height = 0

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

            # Create a transform, that can adjust the alpha channel of the
            # child.
            t = Transform(child=self.child, alpha=self.alpha)

            # Create a render from the child.
            child_render = renpy.render(t, width, height, st, at)

            # Get the size of the child.
            self.width, self.height = child_render.get_size()

            # Create the render we will return.
            render = renpy.Render(self.width, self.height)

            #
            render.place(self.child2)

            # Blit (draw) the child's render to our render.
            render.blit(child_render, (0, 0))

            # Return the render.
            return render

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

            # Compute the distance between the center of this displayable and
            # the mouse pointer. The mouse pointer is supplied in x and y,
            # relative to the upper-left corner of the displayable.
            distance = math.hypot(x - (self.width / 2), y - (self.height / 2))

            # Base on the distance, figure out an 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)

            # If the alpha has changed, trigger a redraw event.
            if alpha != self.alpha:
                self.alpha = alpha
                renpy.redraw(self, 0)

            # Pass the event to our child.
            return self.child.event(ev, x, y, st)

        def visit(self):
            return [ self.child, self.child2 ]
How to use

Code: Select all

label start:

    "start"
    image myxray = XRay("top.png", "botton.png", 200, 100)
    show myxray at truecenter

    ":)"
    hide myxray
    "end"
I hope you find it useful.

References:
https://www.renpy.org/doc/html/udd.html