Ren'Py Help with Creator-Defined Displayables.

Lykanz

Engaged Member
Game Developer
May 2, 2017
2,706
7,276
So I have this code:

Python:
class DdrNote(renpy.Displayable):

    KEY_DICT = {
        "left" : [pygame.K_LEFT, pygame.K_KP4, pygame.K_a],
        "down" : [pygame.K_DOWN, pygame.K_KP2, pygame.K_s],
        "up" : [pygame.K_UP, pygame.K_KP8, pygame.K_w],
        "right" : [pygame.K_RIGHT, pygame.K_KP6, pygame.K_d]
        }

    def __init__(self, image, k):
        super(renpy.Displayable,self).__init__()
        self.image = image
        self.k = k
        self.brightness = 0.0
        self.prev_brightness = 0.0

    def render(self,width,height,st,at):
        t = im.MatrixColor(self.image, im.matrix.brightness(self.brightness))
        child_render = renpy.render(t, width, height, st, at)
        cw, ch = child_render.get_size()

        rv = renpy.Render(cw, ch)
        rv.blit(child_render, (0,0))

        renpy.redraw(self, 0)

        return rv

    def event(self, ev, x, y, st):
        if ev.type == pygame.KEYDOWN:
            if ev.key in self.KEY_DICT[self.k]:
                self.brightness = 0.9
                self.prev_brightness = 0.0
                raise renpy.IgnoreEvent()

        elif ev.type == pygame.KEYUP:
            if ev.key in self.KEY_DICT[self.k]:
                if self.brightness == 0.9:
                    self.brightness = 0.0
                    self.prev_brightness = 0.9
                    raise renpy.IgnoreEvent()
        return None
And the images using it are defined like this:

Python:
DdrNote("images/left_arrow_frame.webp", "left")
It's supposed to change the displayable's brightness when the key related to it is pressed and revert it back to normal when the key is released.

It only works on the screen that is highest in the stack, meaning if the screen has an "use" statement, it stops working for that screen.

If the screen being used also uses that displayable, it'll work on it, but if another screen is used down the code, it won't work for the previous screen either, so on and so forth.

So I guess what I'm looking for is a way for it to work on all screens currently displayed.

What am I missing?
 
Last edited:

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Respected User
Donor
Jun 10, 2017
9,951
14,552
What am I missing?
The fact that use is faking a single screen while in fact displaying more than one.
You use :
Code:
label whatever:
    show screen myScreen
but internally for Ren'py it will look like if you used :
Code:
label whatever:
    show screen myScreen
   show screen usedScreen
That's why Ren'py have both a SetLocalVariable and a SetScreenVariable screen action. One while change the value even from a used screen, the other not. And that's why you encounter this problem.
 

Lykanz

Engaged Member
Game Developer
May 2, 2017
2,706
7,276
The fact that use is faking a single screen while in fact displaying more than one.
You use :
Code:
label whatever:
    show screen myScreen
but internally for Ren'py it will look like if you used :
Code:
label whatever:
    show screen myScreen
   show screen usedScreen
That's why Ren'py have both a SetLocalVariable and a SetScreenVariable screen action. One while change the value even from a used screen, the other not. And that's why you encounter this problem.
Hmm... So there's no way to do what I want in this case?
Sorry if this seems kind of a stupid thing to ask, but I'm still new to this custom displayable thing (in fact, that's the first time I try to create one myself).
 

Lykanz

Engaged Member
Game Developer
May 2, 2017
2,706
7,276
I got some insight from Tom amd he told me that one way to make that work would be to assign an instance of that displayable to a global variable and then use that variable on the screen.

It works... To some extent...

I have setup keypresses on the screen that become usable after some time passes, did that using a timer and a Boolean variable. The thing is, as soon as those keypresses become available, the custom displayables stop working again.

I figured I could use a similar approach and modify the cdd class I created to keep track of the time elapsed since the displayable was shown using the st variable on the event method.

Well... I could do that if I actually knew how to do that, haha. So far all the stuff I tried using pygame events didn't really work. The time elapsed variable on the class doesn't get updated to the current value of st.

How can I make that work?
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Respected User
Donor
Jun 10, 2017
9,951
14,552
I have setup keypresses on the screen that become usable after some time passes, did that using a timer and a Boolean variable. The thing is, as soon as those keypresses become available, the custom displayables stop working again.
Hmm... Without the code it will be difficult to know what is the problem.


Well... I could do that if I actually knew how to do that, haha.
In the render method, do nothing until st reach the expected time.
I don't remember for sure, but I think that for this method, "do nothing" mean that you return an empty render.
 

Lykanz

Engaged Member
Game Developer
May 2, 2017
2,706
7,276
Hmm... Without the code it will be difficult to know what is the problem.




In the render method, do nothing until st reach the expected time.
I don't remember for sure, but I think that for this method, "do nothing" mean that you return an empty render.
It's fine. I ended up scratching the whole idea and rolled back to what I had before. It was just a minor visual effect that I wanted to add anyway.

Thanks for the time tho.