PROBLEM: Physics objects falling down when are only touched (not moved), using the "Drag Platforms" source code.

Hello to everyone!

I’m coding a physics game, and i have found a frustrating behavior when use the “Drag Platforms” source code from the Sample Apps area.

When i touch (without move) a draggable object, it falls down on the scenario, but comes back to the initial position. But the more times you touch (without move) the same object, the more falls down, until it falls out of the platform.

The thing is, this only happen between dynamic objects and static objects. If i have a dynamic object above another dynamic one, it doesn’t fall. And it’s frustrating because after a few touches, the object just disappear from the scenario.

I’m trying to improve the code, stablishing the draggable object from “kinetic” (in the original code) to “static”, and nothing happens.

Another change that doesn’t works is to change the final position from the original source code, like the code following, checking if the initial and final position was changed (if not, doesn’t rest the initial position to the final one):

Original code:

[code]elseif t.isFocus then
if “moved” == phase then
t.x = event.x - t.x0
t.y = event.y - t.y0

elseif “ended” == phase or “cancelled” == phase then
display.getCurrentStage():setFocus( nil )
t.isFocus = false

– Switch body type back to “dynamic”, unless we’ve marked this sprite as a platform
if ( not event.target.isPlatform ) then
event.target.bodyType = “dynamic”
end

end
end[/code]

Modified code:

[code]if “moved” == phase then
if (t.x == t.x0) or (t.u == t.y0) then
t.x = t.x
t.y = t.y
else
t.x = event.x - t.x0
t.y = event.y - t.y0
end

elseif “ended” == phase or “cancelled” == phase then
display.getCurrentStage():setFocus( nil )
t.isFocus = false

if ( not event.target.isPlatform ) then
event.target.bodyType = “dynamic”
end

end
end[/code]

Can anyone help me to find how to solve this small issue? You can try the behavior just downloading and running the sample app “Drag Platforms”.

Thanks in advance :wink: [import]uid: 14235 topic_id: 7232 reply_id: 307232[/import]

Looks like you might have a type-o:

t.u == t.y0  

should probably be

t.y == t.y0  

Right now your condition will probably never return “true”.

Have you turned on debug draw so you can see what is happening with the tempJoints created by the dragBody method?

physics.setDrawMode( "hybrid" )  

will show both the debug draw and your graphics.

I have had trouble with dragBody leaving behind unwanted touch joints, which might cause erratic behavior like what you’ve described. So look for those in debug mode… [import]uid: 36381 topic_id: 7232 reply_id: 25783[/import]

Thanks for your response curiousaaron! Effectively i have a type-o in the code, but is not relevant, because the behavior stills happening.

I have recorded a video to show exactly what happens when you touch a body without moving it, using the “startDrag” function of the “Drag Platforms” sample app (sorry for my poor english):

http://www.youtube.com/watch?v=ADp-HTWlGKI

I am trying absolutely all the combinations of body-types, changing physics engine options, and i’m going completely crazy :frowning: [import]uid: 14235 topic_id: 7232 reply_id: 26254[/import]

does seem like a bug… good find. i would put this over at the bug reports forum. it might be worth putting the drag platforms part of the video first though, then Ansca can see straight away that it’s not your code that’s the problem.

i think it’s because it’s already in collision essentially when the type is set back to dynamic

[import]uid: 6645 topic_id: 7232 reply_id: 26260[/import]

That is strange. If you do think this is a bug, you should turn on debug draw so the Ansca folks can see exactly what their joints and bodies are doing.

In the meantime you might try adjusting the scale of your physics world ( physics.setScale ) and see if increasing or decreasing that value helps with collision testing. I’ve had some luck with that. [import]uid: 36381 topic_id: 7232 reply_id: 26262[/import]

Thanks for the response, jmp909.

Like you, i was thinking that the problem is that the body it’s already in collision when the type is set back to dynamic, so i have made a small change in the code to avoid this, setting the bodytype as “dynamic” OUT of the collision function, with no success.

When the collision ends, or is cancelled, i don’t turn back the body type to “dynamic” directly, but i set the body type to “static”, and after 500 miliseconds, i turn back the body to dynamic. And nothing changes, the behavior stills happenig and the object stills falling down. It’s like if the body doesn’t collides whith the ground.

This is the code of the complete “startDrag” function i0m using, plus the additional function i have created to delay the transform of the body type from “kinematic” to “dynamic” (introducing the intermediate step “static”):

  
-- Function that turns the body-type of all the draggable objects to "dynamic"  
local function convierteDinamico ()  
 caja.bodyType = "dynamic"  
 tablon.bodyType = "dynamic"  
end  
   
  
--\> STARTDRAG  
--\>   
local function startDrag( event )  
 local t = event.target  
   
 local phase = event.phase  
 if "began" == phase then  
 audio.play(sonido\_pulsar)  
 display.getCurrentStage():setFocus( t )  
 t.isFocus = true  
   
 -- Store initial position  
 t.x0 = event.x - t.x  
 t.y0 = event.y - t.y  
 -- Prints the "x" and "y" values of the body, just for debug  
 print( "t.x0 =", t.x0)  
 print( "t.y0 =", t.y0)  
 print( "t.x: ", t.x )  
 print( "t.y: ", t.y )  
 print( "event.x: ", event.x )  
 print( "event.y: ", event.y )  
  
 -- Make body type temporarily "kinematic" (to avoid gravitional forces)  
 event.target.bodyType = "kinematic"  
 physics.setGravity (0, 0)  
 event.target:scale( 1.3, 1.3 )  
 event.target.alpha = 0.8  
  
 -- Stop current motion, if any  
 event.target:setLinearVelocity( 0, 0 )  
 event.target.angularVelocity = 0  
   
 elseif t.isFocus then  
 if "moved" == phase then  
 if (event.x == t.x0) or (event.y == t.y0) then  
 t.x = event.x  
 t.y = event.y  
 print( "Primer IF t.x: ", t.x )  
 print( "Primer IF t.y: ", t.y )  
 print( "Primer IF t.x: ", event.x )  
 print( "Primer IF t.x: ", event.y )  
 else  
 t.x = event.x - t.x0  
 t.y = event.y - t.y0  
 print( "t.x0 =", t.x0)  
 print( "t.y0 =", t.y0)  
 print( "Else t.x: ", t.x )  
 print( "Else t.y: ", t.y )  
 print( "Else event.x: ", event.x )  
 print( "Else event.y: ", event.y )  
 end  
   
 elseif "ended" == phase or "cancelled" == phase then  
 display.getCurrentStage():setFocus( nil )  
 t.isFocus = false  
 audio.play(sonido\_soltar)  
 physics.setGravity (0, 19.8)  
 event.target.bodyType = "static"  
 event.target:scale( 0.77, 0.77 )  
 event.target.alpha = 1.0  
 timer.performWithDelay(500, convierteDinamico, 1 )  
 -- Switch body type back to "dynamic", unless we've marked this sprite as a platform  
 -- if ( not event.target.isPlatform ) then  
 -- event.target.bodyType = "dynamic"  
  
 -- end  
   
 end  
 end  
 -- Stop further propagation of touch event!  
 return true   
end  

So, how can i move this thread to the bug-report forum? (in order to not duplicate threads) [import]uid: 14235 topic_id: 7232 reply_id: 26264[/import]

Hi curiousaaron,

i have changed the scale of my physics world, and the only effect that i can see, is that physic animations runs faster or slowly, (for example, i have a sun rotating, that is just a physic joint between the sun and a transparent image), or that the bodies falls down faster or slowly when i drag it, but the problem is still there.

One thing that changes the behavior, is to change the gravity value. If a set a small gravity, my box falls less than with a big value, so i think that, again, the draggable body acts like if there is no ground after release it. [import]uid: 14235 topic_id: 7232 reply_id: 26289[/import]

Are there any updates on this? I’ve run into the same problem.

My code:

[code]

local physics = require(“physics”)
physics.start()
physics.setGravity( -9.8, 0 )

local bar = display.newRect(0,0,25,960)
physics.addBody(bar, “static”, { density=0.3})

local box = display.newRect(100,100,100,100)
physics.addBody(box, { density=0.3})

local function boxlistener(event)
if event.phase == “began” or event.phase == “moved” or event.phase == “stationary” then
box.x = event.x
box.y = event.y
end
end

box:addEventListener(“touch”, boxlistener )

[/code] [import]uid: 10903 topic_id: 7232 reply_id: 30813[/import]

No news here. I think that this is the reason…

After two weeks loosed trying to fix it, i’m discouraged, i have no time to invest why this “marvelous” behavior happens, and no money to pay the premium support (that, apparently, is the only support that i can receive here…).

Maybe if you’re a Corona subscriptor, can open a support request and have more luck. [import]uid: 14235 topic_id: 7232 reply_id: 30822[/import]

Have you posted this in the bug forum?

Also I can try and shoot it over to Carlos. [import]uid: 10903 topic_id: 7232 reply_id: 30825[/import]

Yes, i have an opened thread in the bugs report forum, with the same luck. [import]uid: 14235 topic_id: 7232 reply_id: 30831[/import]

Resetting the gravity on touch partially solves this issue, but if you drop the object and catch it in the air it continues to fall. [import]uid: 10903 topic_id: 7232 reply_id: 30838[/import]

Here’s a work around, but it’s not a good one if you need gravity to be working for other objects:

[code]
local physics = require(“physics”)
physics.start()
physics.setGravity( -9.8, 0 )

local bar = display.newRect(0,0,25,960)
physics.addBody(bar, “static”, { density=0.3})

local box = display.newRect(100,100,100,100)
physics.addBody(box, { density=0.3})

function doTouch( event )

if event.phase == “began” or event.phase == “moved” then
print(“began phase”)
event.target.alpha = 0.5
display.getCurrentStage():setFocus(event.target)
physics.setGravity( 0, 0 )
box.x = event.x
box.y = event.y
event.target.bodyType = “static”
elseif event.phase == “ended” or event.phase == “cancelled” then
event.target.alpha = 1
print(“end phase”)
display.getCurrentStage():setFocus(nil)
physics.setGravity( -9.8, 0 )
event.target.bodyType = “dynamic”
end

end

box:addEventListener(“touch”, doTouch)
[/code] [import]uid: 10903 topic_id: 7232 reply_id: 30841[/import]

Hi crssmn, i have tried this method a few weeks ago, and doesn’t works for me, because i have more than one object affected with gravity in my game :frowning:

In any case, thanks for the help :wink: [import]uid: 14235 topic_id: 7232 reply_id: 30859[/import]

I was able to comment out the set gravity portion and it worked fine for me. So that is no longer an issue. I find that I can pull the box object through the ground, but am working on a runtime listener that sets it in a specific place if it begins to move through the ground. Something like

if box.x < 0 then
box.x = 0
end

Still thinking about ways to write this for a floating platform, but I assume it can be written. [import]uid: 10903 topic_id: 7232 reply_id: 30860[/import]