Dragging and dropping objects to sensors

Hi all,

I am a Corona newbie, with a lot of previous programming experience.

I am trying to implement a grid of objects, which I will drag other objects onto. I want to highlight target objects in the grid as I drag objects over it, and then if I let go of an object, whilst I am hovering over it, I want to transition the dragged object so that it can settle onto the highlighted grid item.

I have prototyped this using sensors for the grid. This all seems well, with the heavy lifting done by the physics engine. However, I am finding that firstly, sometimes when I drag over the target object the highlighting occurs, but the object doesn’t transition to the “grid” when I release the touch, and secondly, sometimes, multiple “grid” objects are highlighted too when I drag over them. I’m not sure of the best way to highlight a single item.

Any suggestions would be very much appreciated.

Some sample code with one draggable object, and two “grid” objects is shown below. This demonstrates the behaviour that I can’t work out, and runs in the simulator.

Thanks.

[lua]

local physics = require(“physics”)

physics.start()

physics.setDrawMode(“normal”)

physics.setGravity(0,0)

display.setStatusBar( display.HiddenStatusBar )

– Variables

local stateMachine

local currentTarget = nil

local isHighlighted = false

local myTarget = display.newRoundedRect(100,200,69,69,3)

myTarget:setFillColor(100,100,100)

myTarget.name = “holder”

physics.addBody(myTarget,“dynamic”)

myTarget.isSensor = true

local myTarget1 = display.newRoundedRect(180,200,69,69,3)

myTarget1:setFillColor(100,100,100)

myTarget1.name = “holder2”

physics.addBody(myTarget1,“dynamic”)

myTarget1.isSensor = true

local myObject = display.newRoundedRect(50,50,67,67,3); 

myObject:setFillColor(0,0,255)

myObject.x = 100

myObject.y = 100

myObject.name = “letter”

physics.addBody(myObject,“static”)

function myObject:touch(event)

    local t = event.target

    – printTouch(event)

    local phase = event.phase

    if phase == “began” then

    – Make target the top-most object

    local parent = t.parent

    parent:insert(t)

    display.getCurrentStage():setFocus(t)

    – This flag is to prevent spurious events being sent to the target

    t.isFocus = true

    – Store initial position

    t.x0 = event.x - t.x

    t.y0 = event.y - t.y

    – Make myObject temporarily kinematic

    event.target.bodyType = “kinematic”

    – Stop current motion, if any

    event.target:setLinearVelocity(0,0)

    event.target.angularVelocity = 0

    elseif t.isFocus then

        if phase == “moved” then

            t.x = event.x - t.x0

            t.y  = event.y - t.y0

        elseif phase == “ended” or phase == “cancelled” then

            if currentTarget ~= nil and isHighlighted then

                – Move piece to target

                transition.to(t,{

                    time = 150,

                    x = currentTarget.x,

                    y = currentTarget.y

                })

                currentTarget = nil

                isHighlighted = false

            end

            display.getCurrentStage():setFocus(nil)

            t.isFocus = false

            – Switch body type back to “static”

            event.target.bodyType = “static”

        end

    end

    

    return true

end

– make myObject listen for touch events

myObject:addEventListener(“touch”,myObject)

local function onLocalCollision( self, event )

    if ( event.phase == “began” ) then

        print( self.name … ": collision began with " … event.other.name )

        stateMachine:dispatchEvent({name=“highlight”, state=“on”, customData = self});

    elseif ( event.phase == “ended” ) then

        print( self.name … ": collision ended with " … event.other.name )

        stateMachine:dispatchEvent({name=“highlight”, state=“off”, customData = self});

    end

end

myTarget.collision = onLocalCollision

myTarget:addEventListener( “collision”, myTarget )

myTarget1.collision = onLocalCollision

myTarget1:addEventListener( “collision”, myTarget1 )

–Create an empty group to use as a listener for custom events

stateMachine = display.newGroup();

–Centralized logic control

function stateMachine:highlight(e)

    if(e.state == “on”) then

        --print("Highlight on: " … e.customData.object1.name)

        currentTarget = e.customData

        isHighlighted = true

        e.customData:setFillColor(255,255,0)

    elseif(e.state == “off”) then

        currentTarget = nil

        isHighlighted = false

        --print("Highlight off: " … e.customData.other.name)

        e.customData:setFillColor(100,100,100)

    end

    

end

stateMachine:addEventListener(“highlight”, stateMachine);

[/lua]

Your problem is that currentTarget is a single variable for two grids. The reason why it sometimes isn’t transitioning is because when you hover over one grid it sets currentTarget to it, then you hover over the other sets it again but then you hover off the first grid and it turns it off. So when you let go it’s state is off even though you are currently on one grid, but currentTarget takes whatever you did last, so if you hovered off a grid last it will be set to nil and isHighlighted to false. If you have both of them highlighted it will hover to the last grid since thats the info currentTarget last received.

This looks fun. Question is, you probably want your code to be dynamic in case you ever want to add 15 holders for example? And not just a workaround for a few objects? If you still need help I’ll gladly look at this when I get home tonight

Hi all,

I managed to fix up the state thing, and apply it to an array of generated objects, but still had a couple of problems. Then I found David McCuskey’s dmc_dragdrop library (available in the Share your code section of Corona’s website), which works perfectly.

I think I might go back and learn a bit more about Corona before I post any more queries :slight_smile:

Thanks, Andrew

hey Andrew,

i’m really glad that you found my library useful. good luck on your Corona path. :slight_smile:

cheers,
dmc

Your problem is that currentTarget is a single variable for two grids. The reason why it sometimes isn’t transitioning is because when you hover over one grid it sets currentTarget to it, then you hover over the other sets it again but then you hover off the first grid and it turns it off. So when you let go it’s state is off even though you are currently on one grid, but currentTarget takes whatever you did last, so if you hovered off a grid last it will be set to nil and isHighlighted to false. If you have both of them highlighted it will hover to the last grid since thats the info currentTarget last received.

This looks fun. Question is, you probably want your code to be dynamic in case you ever want to add 15 holders for example? And not just a workaround for a few objects? If you still need help I’ll gladly look at this when I get home tonight

Hi all,

I managed to fix up the state thing, and apply it to an array of generated objects, but still had a couple of problems. Then I found David McCuskey’s dmc_dragdrop library (available in the Share your code section of Corona’s website), which works perfectly.

I think I might go back and learn a bit more about Corona before I post any more queries :slight_smile:

Thanks, Andrew

hey Andrew,

i’m really glad that you found my library useful. good luck on your Corona path. :slight_smile:

cheers,
dmc

I am an extreme newbie as well. I have been searching for something similar to your code for a game I am creating for a class. I have created some rectangles and put them in a group and have made some other objects able to be dragged. Would you mind sharing what you have come up with? I understand a bit about what you posted here, but I don’t know how to get past the problem you were running into either.

I am an extreme newbie as well. I have been searching for something similar to your code for a game I am creating for a class. I have created some rectangles and put them in a group and have made some other objects able to be dragged. Would you mind sharing what you have come up with? I understand a bit about what you posted here, but I don’t know how to get past the problem you were running into either.