Drag and drop with returning drag to his original position

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
abeplaga
Regular
Posts: 35
Joined: Mon Oct 15, 2018 10:09 am
Contact:

Drag and drop with returning drag to his original position

#1 Post by abeplaga »

Hi again.

I would like to have a simple drag and drop system. I made one with one object drag to one area drop but now I want that the drag object returns to its original position if the player doesn't place it in the drop area.

I found this thread with a solution viewtopic.php?t=38835 but there's for more than one objetc drop, and honestly, I don't understand very much (I'm learning Ren'py and I'm not programmer, maybe a mixture doomed to constant fails) :s Perhaps with one object drag would be more simple that code of that thread.

I tried to understand and simplify by myself but doesn't work. This is what I've done (possibly an aberration):

This is screens.rpy

Code: Select all

init python:

    def myobject_drag(drags, drop):

        if not drop:
            return

        store.myobject = drags[0].drag_name
        store.myarea = drop.drag_name

        return True

screen send_object_to_area:
    modal True

    draggroup:

        drag:
            drag_name "myobject"
            idle_child "myobject_idle.png"
            hover_child "myobject_hover.png"
            droppable False
            dragged my_dragged
            xpos 288 ypos 593

        drag:
            drag_name "myarea"
            idle_child "myarea_idle.png"
            selected_idle_child "myarea_hover.png"
            draggable False
            xpos 1318 ypos 79


init python:
def my_dragged (drags, drop):

        if not drop:
                if drags[0].drag_name == "myobject":
                    drags[0].xpos = 288
                    drags[0].ypos = 593
        return
And this is the code of script.rpy

Code: Select all

call send_object_to_area
I think it's not necessary use item list compare with the example of another thread because here it's only one object to drop. Maybe I'm wrong but I don't know how could it works...

························

My drag and drop code without returning drag is this:

Code: Select all

init python:

    def myobject_drag(drags, drop):

        if not drop:
            return

        store.myobject = drags[0].drag_name
        store.myarea = drop.drag_name

        return True

screen send_object_to_area:
    modal True

    draggroup:

        drag:
            drag_name "myobject"
            idle_child "myobject_idle.png"
            hover_child "myobject_hover.png"
            droppable False
            dragged myobject_drag
            xpos 288 ypos 593

        drag:
            drag_name "myarea"
            idle_child "myarea_idle.png"
            selected_idle_child "myarea_hover.png"
            draggable False
            xpos 1318 ypos 79
How could add a returning drag system? I tried to modify in other ways but doesn't work...

If anyone can help me I will thank you very much!

User avatar
Alex
Lemma-Class Veteran
Posts: 3090
Joined: Fri Dec 11, 2009 5:25 pm
Contact:

Re: Drag and drop with returning drag to his original position

#2 Post by Alex »

If you have just one object you can use variables to store the initial position of this object, like

Code: Select all

default my_xpos = 288
default my_ypos = 593
Then in your "myobject_drag" you can check if the object wasn't droped over droppable area and move it back.
(edited code)

Code: Select all

init python:

    def myobject_drag(drags, drop):

        if not drop: # if object was moved and dropped somewhere onscreen but not over droppable
            drags[0].snap(my_xpos, my_ypos, 0.1)
            return

        store.myobject = drags[0].drag_name
        store.myarea = drop.drag_name

        return True


screen send_object_to_area:
    modal True

    draggroup:

        drag:
            drag_name "myobject"
            idle_child "myobject_idle.png"
            hover_child "myobject_hover.png"
            droppable False
            dragged myobject_drag
            xpos my_xpos ypos my_ypos

        drag:
            drag_name "myarea"
            idle_child "myarea_idle.png"
            selected_idle_child "myarea_hover.png"
            draggable False
            xpos 1318 ypos 79
Last edited by Alex on Tue Oct 16, 2018 1:31 am, edited 1 time in total.

User avatar
abeplaga
Regular
Posts: 35
Joined: Mon Oct 15, 2018 10:09 am
Contact:

Re: Drag and drop with returning drag to his original position

#3 Post by abeplaga »

Alex wrote: Mon Oct 15, 2018 2:39 pm If you have just one object you can use variables to store the initial position of this object, like Then in your "myobject_drag" you can check if the object wasn't droped over droppable area and move it back.
Change it, thanks! But it doesn't work :(

When I drop on non-drop area it appears this error:

Code: Select all

I'm sorry, but an uncaught exception occurred.

While running game code:
  File "game/script.rpy", line 287, in script
    call screen send_object_to_area
  File "renpy/common/000statements.rpy", line 519, in execute_call_screen
    store._return = renpy.call_screen(name, *args, **kwargs)
  File "game/screens.rpy", line 1945, in myobject_drag
    store.myarea = drop.drag_name
AttributeError: 'NoneType' object has no attribute 'drag_name'

-- Full Traceback ------------------------------------------------------------

Full traceback:
  File "game/script.rpy", line 287, in script
    call screen send_object_to_area
  File "C:\Program Files (x86)\renpy-7.1.0-sdk\renpy\ast.py", line 1848, in execute
    self.call("execute")
  File "C:\Program Files (x86)\renpy-7.1.0-sdk\renpy\ast.py", line 1836, in call
    return renpy.statements.call(method, parsed, *args, **kwargs)
  File "C:\Program Files (x86)\renpy-7.1.0-sdk\renpy\statements.py", line 179, in call
    return method(parsed, *args, **kwargs)
  File "renpy/common/000statements.rpy", line 519, in execute_call_screen
    store._return = renpy.call_screen(name, *args, **kwargs)
  File "C:\Program Files (x86)\renpy-7.1.0-sdk\renpy\exports.py", line 2723, in call_screen
    rv = renpy.ui.interact(mouse="screen", type="screen", roll_forward=roll_forward)
  File "C:\Program Files (x86)\renpy-7.1.0-sdk\renpy\ui.py", line 289, in interact
    rv = renpy.game.interface.interact(roll_forward=roll_forward, **kwargs)
  File "C:\Program Files (x86)\renpy-7.1.0-sdk\renpy\display\core.py", line 2662, in interact
    repeat, rv = self.interact_core(preloads=preloads, trans_pause=trans_pause, **kwargs)
  File "C:\Program Files (x86)\renpy-7.1.0-sdk\renpy\display\core.py", line 3467, in interact_core
    rv = root_widget.event(ev, x, y, 0)
  File "C:\Program Files (x86)\renpy-7.1.0-sdk\renpy\display\layout.py", line 995, in event
    rv = i.event(ev, x - xo, y - yo, cst)
  File "C:\Program Files (x86)\renpy-7.1.0-sdk\renpy\display\layout.py", line 995, in event
    rv = i.event(ev, x - xo, y - yo, cst)
  File "C:\Program Files (x86)\renpy-7.1.0-sdk\renpy\display\layout.py", line 995, in event
    rv = i.event(ev, x - xo, y - yo, cst)
  File "C:\Program Files (x86)\renpy-7.1.0-sdk\renpy\display\screen.py", line 697, in event
    rv = self.child.event(ev, x, y, st)
  File "C:\Program Files (x86)\renpy-7.1.0-sdk\renpy\display\layout.py", line 995, in event
    rv = i.event(ev, x - xo, y - yo, cst)
  File "C:\Program Files (x86)\renpy-7.1.0-sdk\renpy\display\dragdrop.py", line 757, in event
    return super(DragGroup, self).event(ev, x, y, st)
  File "C:\Program Files (x86)\renpy-7.1.0-sdk\renpy\display\layout.py", line 995, in event
    rv = i.event(ev, x - xo, y - yo, cst)
  File "C:\Program Files (x86)\renpy-7.1.0-sdk\renpy\display\dragdrop.py", line 655, in event
    rv = run(drag.dragged, joined, drop)
  File "C:\Program Files (x86)\renpy-7.1.0-sdk\renpy\display\behavior.py", line 315, in run
    return action(*args, **kwargs)
  File "game/screens.rpy", line 1945, in myobject_drag
    store.myarea = drop.drag_name
AttributeError: 'NoneType' object has no attribute 'drag_name'
Reading that message error I tried to change the if of non-drop after the store.myarea = drop.drag_name (I thank it's that attribute drag_name (trying to fix it by myself) but nothing changes.

Code: Select all

    def myobject_drag(drags, drop):
       
        store.myobject = drags[0].drag_name
        store.myarea = drop.drag_name
 	
 	if not drop: # if object was moved and dropped somewhere onscreen but not over droppable
            drags[0].snap(my_xpos, my_ypos, 0.1)
            
        return True

User avatar
abeplaga
Regular
Posts: 35
Joined: Mon Oct 15, 2018 10:09 am
Contact:

Re: Drag and drop with returning drag to his original position

#4 Post by abeplaga »

Double post because I found a solution after several trials and errors!

The code of Alex is good but in "if no drop" part it has to add a return

Code: Select all

 if not drop:
            drags[0].snap(my_xpos, my_ypos, 0.1)
            return
And it works! <3 Drag and drop with returning drag, yay!

User avatar
Alex
Lemma-Class Veteran
Posts: 3090
Joined: Fri Dec 11, 2009 5:25 pm
Contact:

Re: Drag and drop with returning drag to his original position

#5 Post by Alex »

abeplaga wrote: Mon Oct 15, 2018 7:34 pm Double post because I found a solution after several trials and errors!
Oops, glad you found this...;)

Post Reply

Who is online

Users browsing this forum: Bing [Bot], Google [Bot]