Distinguish, drag, drop creator-defined displayable

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Post Reply
Message
Author
User avatar
Eliont
Regular
Posts: 88
Joined: Thu Aug 06, 2009 6:51 am
Completed: Begin of Evangelion, SAO - Smile of the black cat, SAO - Project "Ceramic Heart"
Projects: Legends of Alkion
Location: Russia
Contact:

Distinguish, drag, drop creator-defined displayable

#1 Post by Eliont » Fri May 31, 2019 11:46 am

Hello and good time of day.
Following https://www.renpy.org/doc/html/udd.html i managed to create two custom displayable with updateable text on them.
But how to distinguish what displayable clicked, move them, and detect collision?

Image

displayable code:

Code: Select all

init python:

    import math,pygame

    class Card(renpy.Displayable):

        def __init__(self, child, xsize,ysize, **kwargs):
            super(Card, self).__init__(**kwargs)

            self.xpos = 0 
            self.ypos = 0 
            self.xsize = xsize 
            self.ysize = ysize 
            self.x_offset = 0 
            self.y_offset = 0 
            
            self.child = renpy.displayable(child)
            self.text = Text("{color=#000}x=%d y=%d"%(self.xpos,self.ypos)) 
            
            self.dragging = False
            
            
            
        def render(self, width, height, st, at):
            self.text = Text("{color=#000}x=%d y=%d"%(self.xpos,self.ypos)) 
            
            child_transform = Transform(child=self.child, xpos=self.xpos, ypos=self.ypos)
            text_transform = Transform(child=self.text, xpos=self.xpos, ypos=self.ypos)
            
            child_render = renpy.render(child_transform, self.xsize, self.ysize, st, at)
            text_render = renpy.render(text_transform, width, height, st, at) 

            render = renpy.Render(self.xsize, self.ysize)

            render.blit(child_render, (0, 0))
            render.blit(text_render, (10,10)) 

            return render

            
            
        def event(self, ev, x, y, st):
            if ev.type == pygame.MOUSEBUTTONDOWN and ev.button == 1:
                self.dragging = True
                
            elif ev.type == pygame.MOUSEMOTION and self.dragging:
                self.xpos = x 
                self.ypos = y   
                renpy.redraw(self, 0)
            
            elif ev.type == pygame.MOUSEBUTTONUP and ev.button == 1: 
                self.dragging = False
                self.xpos = x 
                self.ypos = y   
                renpy.redraw(self, 0)

            return self.child.event(ev, x, y, st)

            
            
        def visit(self):
            return [ self.child, self.text ]
script.rpy:

Code: Select all

screen udd:
    add Card(Solid((255,255,255,255)),300,300):
        xalign 0.75
        yalign 0.5
        
    add Card(Solid((255,255,255,255)),300,300):
        xalign 0.25
        yalign 0.5

label start:
    show screen udd

    while True:
        $ui.interact()

    return
Thanks in advance.

Btw, is there more comprehensive guide / cookbook for UDD thing?
Scripting on Ren'Py itself since 2009, but just did not use that functional before and now can't figure out UDD interface and methods usage.

User avatar
Eliont
Regular
Posts: 88
Joined: Thu Aug 06, 2009 6:51 am
Completed: Begin of Evangelion, SAO - Smile of the black cat, SAO - Project "Ceramic Heart"
Projects: Legends of Alkion
Location: Russia
Contact:

Re: Distinguish, drag, drop creator-defined displayable

#2 Post by Eliont » Sun Jun 02, 2019 12:52 am

Thanks to Xela, working code for this small example:

Code: Select all

    class Card(renpy.Displayable):

        def __init__(self, child, xsize,ysize, **kwargs):
            super(Card, self).__init__(**kwargs)

            self.xsize = xsize 
            self.ysize = ysize 
            self.x_offset = 0 
            self.y_offset = 0 
            
            self.rect = pygame.Rect((0, 0), (self.xsize,self.ysize))
            
            self.child = renpy.displayable(child)
            self.text = Text("{color=#000}x=%d y=%d"%(0,0)) 
            
            self.dragging = False

            
        def render(self, width, height, st, at):
            self.text = Text("{color=#000}x=%d y=%d"%(self.rect.x,self.rect.y))         

            render = renpy.Render(self.xsize, self.ysize)

            xpos = self.rect.x-self.x_offset
            ypos = self.rect.y+10-self.y_offset
            
            render.place(self.child,x=xpos,y=ypos,width=self.xsize,height=self.ysize)
            render.place(self.text,x=xpos+10,y=ypos+10,width=self.xsize,height=self.ysize)

            return render

            
        def event(self, ev, x, y, st):
            if ev.type == pygame.MOUSEBUTTONDOWN and ev.button == 1:
                if self.rect.collidepoint(x, y):
                    self.dragging = True
                    self.x_offset = x - self.rect.x
                    self.y_offset = y - self.rect.y
                
            elif ev.type == pygame.MOUSEMOTION and self.dragging:
                self.rect.x = x 
                self.rect.y = y
                renpy.redraw(self, 0)
            
            elif ev.type == pygame.MOUSEBUTTONUP and ev.button == 1 and self.dragging: 
                self.dragging = False
                self.rect.x = x - self.x_offset
                self.rect.y = y - self.y_offset      
                self.x_offset = 0
                self.y_offset = 0                
                renpy.redraw(self, 0)

            return self.child.event(ev, x, y, st)

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

Post Reply

Who is online

Users browsing this forum: No registered users