[SOLVED] object drag question

I have a moving object (with translate) that is draggable. If I click on the background, wait until the object moves under the mouse, and then release, the “begun” and “moved” phases get skipped and I go straight to the “ended” phase.

I bet there is something really simple to do to fix it, but I’ve tried everything in my power (not a huge resource yet) and can’t figure it. Any thoughts?

[import]uid: 96383 topic_id: 17077 reply_id: 317077[/import]

It’s actually the “began” phase. I’ve ran into this issue before and it was always a very simple fix, something I missed. If you paste your code someone will probably be able to help you much easier. [import]uid: 52430 topic_id: 17077 reply_id: 64110[/import]

Thanks Jonathan, here’s the code. or a trimmed down version which still has the problem. I’d sure appreciate any help.

[lua]display.setStatusBar(display.HiddenStatusBar)

local background = display.newImage (“farmbg.jpg”)


– the tail –

local tail = display.newImage (“tail.png”)
tail.x = math.random( 21, 300)
tail.y = math.random( 21, 460)
local xPosTail,yPosTail = math.random( 40, 280),math.random( 20, 460)

tailSpeedX = .4
tailSpeedY = .4


– BOUNCE the tail around –

local function onMoveTail(event)

xPosTail = xPosTail + ( 2.8 * tailSpeedX );
yPosTail = yPosTail + ( 2.2 * tailSpeedY );

if (xPosTail > display.contentWidth - 20 or xPosTail < 20) then
tailSpeedX = tailSpeedX * -1;
end

if (yPosTail > display.contentHeight - 20 or yPosTail < 20) then
tailSpeedY = tailSpeedY * -1;
end

tail:translate( xPosTail - tail.x, yPosTail - tail.y)

end


– DRAG THE TAIL

function tail:touch( event )

if event.phase == “began” then

tail.x =event.x
tail.y = event.y

self.markX = self.x – store x location of tail
self.markY = self.y – store y location of tail

display.getCurrentStage():setFocus(event.target)

tail.isVisible = not tail.isVisible

elseif event.phase == “moved” then

local x = (event.x - event.xStart) + self.markX
local y = (event.y - event.yStart) + self.markY

self.x, self.y = x, y

local xdist=tail.x-donkey.x
local ydist=tail.y-donkey.y

elseif event.phase == “ended” then

local backButton = display.newImage (“againButton.png”)
backButton.x = 160
backButton.y = 455
localGroup:insert(backButton)
backButton:addEventListener( “touch”, pressBack)

local xdist=tail.x-donkey.x
local ydist=tail.y-donkey.y

tail:removeEventListener( “touch”, tail )
display.getCurrentStage():setFocus(tail, nil)

end
return true
end


– listeners –

tail:addEventListener( “touch”, tail )
Runtime:addEventListener(“enterFrame”, onMoveTail)

------------------------------------------------------------------------------------[/lua]
[import]uid: 96383 topic_id: 17077 reply_id: 64118[/import]

Hmm, that’s strange.

What happens if you rip everything out of your tail:touch() function and replace it with the following:

print( event.phase )[/code]Are the phases showing up? I pasted your example into a new project and did the above and was able to get all three phases. [import]uid: 52430 topic_id: 17077 reply_id: 64137[/import]

The phase show up. But if click away from the object, let it drift under the mouse, and then release, I get the ended phase. All I want is for the event not to register at all if I haven’t started the click on the object. Is that possible?

[import]uid: 96383 topic_id: 17077 reply_id: 64140[/import]

I am just curious on your line 78…

display.currentStage:setFocus(nil)

would be much better

cheers,

?:slight_smile: [import]uid: 3826 topic_id: 17077 reply_id: 64143[/import]

Thanks JayantV. I replaced it (thank god you can’t see the rest of the code, I might be kicked of the forum :slight_smile: but still the problem persists. If I click off of the object, and then the object moves under the curser and I release, I get the “ended” phase, without the other two phases, which creates all kinda problems. I’ve tried a ton of different things to rectify this. Do you have any suggestions?

[import]uid: 96383 topic_id: 17077 reply_id: 64163[/import]

ok, going by instinct on this one…

Do you have any overlapping objects? Coz one might be getting the began and moved and only when it is released (setFocus(nil)) your other object gets the ended phase.

cheers,

?:slight_smile: [import]uid: 3826 topic_id: 17077 reply_id: 64164[/import]

The moving object in question is the only one on the stage - except for the BG, would that count?. I’ve pared the code down even further as per jonathonbeebe’s suggestion. There’s really not much to it. He is thinking I have missed something simple, probably true. I’ve wracked my brain’s for a day and a half.

[lua]display.setStatusBar(display.HiddenStatusBar)

local background = display.newImage (“farmbg.jpg”)


– the tail –

local tail = display.newImage (“tail.png”)
tail.x = math.random( 21, 300)
tail.y = math.random( 21, 460)
local xPosTail,yPosTail = math.random( 40, 280),math.random( 20, 460)

tailSpeedX = .4
tailSpeedY = .4


– BOUNCE the tail around –

local function onMoveTail(event)

xPosTail = xPosTail + ( 2.8 * tailSpeedX );
yPosTail = yPosTail + ( 2.2 * tailSpeedY );

if (xPosTail > display.contentWidth - 20 or xPosTail < 20) then
tailSpeedX = tailSpeedX * -1;
end

if (yPosTail > display.contentHeight - 20 or yPosTail < 20) then
tailSpeedY = tailSpeedY * -1;
end

tail:translate( xPosTail - tail.x, yPosTail - tail.y)

end


– DRAG THE TAIL

function tail:touch( event )

if event.phase == “began” then

print( event.phase )

elseif event.phase == “moved” then

print( event.phase )

elseif event.phase == “ended” then

print( event.phase )

end
return true
end


– listeners –

tail:addEventListener( “touch”, tail )
Runtime:addEventListener(“enterFrame”, onMoveTail)

------------------------------------------------------------------------------------[/lua]
[import]uid: 96383 topic_id: 17077 reply_id: 64167[/import]

I think this is normal for the way you are running your test.

You are clicking on the screen, holding the mouse button down and waiting for the object to move under your cursor? Is that correct?

If you just click on the object, drag it, and then release you should get all of your prints to come out. [import]uid: 67839 topic_id: 17077 reply_id: 64174[/import]

right, had a detailed look at your code

with the code you have posted, you do not get exclusive events. so your touch code has to change to

function tail:touch( event )  
 local target = event.target  
  
 if event.phase == "began" then  
 display.currentStage:setFocus(target)  
 target.setFocus=true  
 print( event.phase )  
 elseif event.phase == "moved" and target.setFocus then  
 print( event.phase )  
 elseif event.phase == "ended" then  
 display.currentStage:setFocus(nil)  
 target.setFocus = false  
 print( event.phase )  
 end  
  
 return true   
end  

Now you will not get a moved before you *actually* begin on the tail object and where ever you finish, the tail will get a ended event too

cheers,

?:slight_smile: [import]uid: 3826 topic_id: 17077 reply_id: 64179[/import]

Thanks so much for your help, but I think I’m probably not explaining my problem very well, because I coped the code in and am still having the issue.

I have an object moving on the screen which the user must touch to stop, and then move to accomplish other tasks, before releasing. But the object moves quickly.

So the user has a hard time aiming their finger (part of the game) and occasionally misses, touches alongside (not on top of) the object, but the object moves under their finger before the user lifts it to try again.

But what happens then (but is not supposed to happen) is that the the “ended” phase of the sequence is triggered, and since the “began” and “moved” phases have been skipped, all hell breaks loose :slight_smile:

With the code you have kindly constructed, I am still having that issue. Is this, as elbowroomapps suggests, simply the way Corona works with no way around it? [import]uid: 96383 topic_id: 17077 reply_id: 64186[/import]

Can you post a video or the full code to see, coz there is definitely some things that is off synch. If that code block does not work for you, then I am sure that I am not *entirely* understanding what you are after.

cheers,

?:slight_smile: [import]uid: 3826 topic_id: 17077 reply_id: 64187[/import]

Hey JayantV, here is the version of the code that does not have your adjustment installed. I just wanted you to see it. If you copied pasted you would be able to observe my problem - namely, clicking and dragging on the tail object then releasing brings up the “backButton” object, correctly, but clicking off of the “tail” object, then releasing when the object moves under the cursor, also brings up the “backButton” object.

I have also pasted in the version with your code after this, but I am getting an error: attempt to index global ‘target’ (a nil value), so I suspect I am not putting your code in properly.
[lua]display.setStatusBar(display.HiddenStatusBar)


– the tail –

local tail = display.newRect(0, 0, 20, 20)
tail.x = math.random( 21, 300)
tail.y = math.random( 21, 460)
local xPosTail,yPosTail = math.random( 40, 280),math.random( 20, 460)

tailSpeedX = .4
tailSpeedY = .4


– BOUNCE the tail around –

local function onMoveTail(event)

xPosTail = xPosTail + ( 2.8 * tailSpeedX );
yPosTail = yPosTail + ( 2.2 * tailSpeedY );

if (xPosTail > display.contentWidth - 20 or xPosTail < 20) then
tailSpeedX = tailSpeedX * -1;
end

if (yPosTail > display.contentHeight - 20 or yPosTail < 20) then
tailSpeedY = tailSpeedY * -1;
end

tail:translate( xPosTail - tail.x, yPosTail - tail.y)

end


– DRAG THE TAIL

function tail:touch( event )

if event.phase == “began” then

tail.x =event.x
tail.y = event.y

self.markX = self.x – store x location of tail
self.markY = self.y – store y location of tail

display.getCurrentStage():setFocus(event.target)

Runtime:removeEventListener(“enterFrame”, onMoveTail)

elseif event.phase == “moved” then

local x = (event.x - event.xStart) + self.markX
local y = (event.y - event.yStart) + self.markY

self.x, self.y = x, y

elseif event.phase == “ended” then

local backButton = display.newRect(0, 0, 80, 80)
backButton.x = 160
backButton.y = 455

tail:removeEventListener( “touch”, tail )
display.getCurrentStage():setFocus(tail, nil)

end
return true
end


– listeners –

tail:addEventListener( “touch”, tail )
Runtime:addEventListener(“enterFrame”, onMoveTail)[/lua]

And here is the version with your code, so kindly provided:

[lua]display.setStatusBar(display.HiddenStatusBar)


– the tail –

local tail = display.newRect(0, 0, 20, 20)
tail.x = math.random( 21, 300)
tail.y = math.random( 21, 460)
local xPosTail,yPosTail = math.random( 40, 280),math.random( 20, 460)

tailSpeedX = .4
tailSpeedY = .4


– BOUNCE the tail around –

local function onMoveTail(event)

xPosTail = xPosTail + ( 2.8 * tailSpeedX );
yPosTail = yPosTail + ( 2.2 * tailSpeedY );

if (xPosTail > display.contentWidth - 20 or xPosTail < 20) then
tailSpeedX = tailSpeedX * -1;
end

if (yPosTail > display.contentHeight - 20 or yPosTail < 20) then
tailSpeedY = tailSpeedY * -1;
end

tail:translate( xPosTail - tail.x, yPosTail - tail.y)

end


– DRAG THE TAIL

function tail:touch( event )

if event.phase == “began” then
display.currentStage:setFocus(target)
target.setFocus=true
tail.x =event.x
tail.y = event.y

self.markX = self.x – store x location of tail
self.markY = self.y – store y location of tail

Runtime:removeEventListener(“enterFrame”, onMoveTail)

elseif event.phase == “moved” and target.setFocus then

local x = (event.x - event.xStart) + self.markX
local y = (event.y - event.yStart) + self.markY

self.x, self.y = x, y

elseif event.phase == “ended” then
display.currentStage:setFocus(nil)
target.setFocus = false

local backButton = display.newRect(0, 0, 80, 80)
backButton.x = 160
backButton.y = 455

tail:removeEventListener( “touch”, tail )

end
return true
end


– listeners –

tail:addEventListener( “touch”, tail )
Runtime:addEventListener(“enterFrame”, onMoveTail)[/lua]
[import]uid: 96383 topic_id: 17077 reply_id: 64195[/import]

Here is what I would try.

Make the entire screen a touchable object.

background:addEventListener( “touch”, background )

When you get the event.phase == begin, compare the coordinates of the event to the coordinates of tail.

if math.abs(event.x - tail.x) < XYZ and math.abs(event.y - tail.y) then

stop Runtime event listener and set some flag (DRAG = true)

You may have to experiment to decide the best value for XYZ.

Change the moved code to
if event.phase == moved and DRAG ==true

run your original code. [import]uid: 67839 topic_id: 17077 reply_id: 64201[/import]

Easiest solution was to set a variable in the “began” phase of the dragged object, and check for it in the ended phase of that object, so as not to trigger the ended phase if the began phase had not happened, just in case any other helpless newbies stumble on this problem and search the forums, maybe it will help :slight_smile:

[import]uid: 96383 topic_id: 17077 reply_id: 64355[/import]