Some more thoughts after discussing with an engineer here…in the startDrag() function posted in the test case, the x/y display coordinates are being manipulated directly, outside the Box2D physical world–in godlike fashion, so to speak. This makes the physics gods angry. Using a touch joint to perform the drag (mouse joint in Box2d lingo) keeps everything consistent within the physical world. For instance, this similar Box2D/AS3 rope sample uses a touch/mouse joint to make the ball at the end of the rope draggable:
http://www.emanueleferonato.com/2009/10/05/basic-box2d-rope/
Below is the Corona version of the same sample. If there’s a use case/scenario that we’re not understanding, please let us know/post some code.
thanks,
-Tim
[code]
–> Setup Display
display.setStatusBar (display.HiddenStatusBar)
–> Start Physics
local physics = require (“physics”)
physics.start ()
physics.setGravity (0, 10)
–physics.setDrawMode (“hybrid”)
–> Create Walls
local leftWall = display.newRect (0, 0, 1, display.contentHeight)
local rightWall = display.newRect (display.contentWidth, 0, 1, display.contentHeight)
local ceiling = display.newRect (0, 0, display.contentWidth, 1)
local floor = display.newRect (0, display.contentHeight, display.contentWidth, 1)
physics.addBody (leftWall, “static”, {bounce = 0.0, friction = 10})
physics.addBody (rightWall, “static”, {bounce = 0.0, friction = 10})
physics.addBody (ceiling, “static”, {bounce = 0.0, friction = 10})
physics.addBody (floor, “static”, {bounce = 0.0, friction = 10})
local xCenter = 160
local wCeil = 120
local hCeil = 20
local ceiling = display.newRect( xCenter - wCeil*0.5, 0, wCeil, hCeil )
physics.addBody( ceiling, “static”, { density=0, friction=0.5,bounce=0.2 } )
local prevBody = ceiling
local w,h = 10,50
local halfW,halfH = 0.5*w,0.5*h
– center of body
local x = xCenter
local y = hCeil - halfH
local yJoint = y - halfH
– rope
for i = 1, 5 do
y = y + h
yJoint = yJoint + h
local body = display.newRect( x-halfW, y-halfH, w, h )
body:setFillColor( 255, 0, 0, 128 )
physics.addBody( body, { density=50, friction=0.5, bounce=.2 })
local joint = physics.newJoint( “pivot”, prevBody, body, xCenter, yJoint )
prevBody = body
end
– final body
y = y + halfH
local r = h*0.5
local body = display.newCircle( x, y, r )
body:setFillColor( 0, 0, 255, 128 )
physics.addBody( body, { density=2, friction=0.5, bounce=.2, radius=r })
local joint = physics.newJoint( “pivot”, prevBody, body, xCenter, y )
local ball = body
function dragBody( event, params )
local body = event.target
local phase = event.phase
local stage = display.getCurrentStage()
if “began” == phase then
stage:setFocus( body, event.id )
body.isFocus = true
– Create a temporary touch joint and store it in the object for later reference
if params and params.center then
– drag the body from its center point
body.tempJoint = physics.newJoint( “touch”, body, body.x, body.y )
else
– drag the body from the point where it was touched
body.tempJoint = physics.newJoint( “touch”, body, event.x, event.y )
end
– Apply optional joint parameters
if params then
local maxForce, frequency, dampingRatio
if params.maxForce then
– Internal default is (1000 * mass), so set this fairly high if setting manually
body.tempJoint.maxForce = params.maxForce
end
if params.frequency then
– This is the response speed of the elastic joint: higher numbers = less lag/bounce
body.tempJoint.frequency = params.frequency
end
if params.dampingRatio then
– Possible values: 0 (no damping) to 1.0 (critical damping)
body.tempJoint.dampingRatio = params.dampingRatio
end
end
elseif body.isFocus then
if “moved” == phase then
– Update the joint to track the touch
body.tempJoint:setTarget( event.x, event.y )
elseif “ended” == phase or “cancelled” == phase then
stage:setFocus( body, nil )
body.isFocus = false
– Remove the joint when the touch ends
body.tempJoint:removeSelf()
end
end
– Stop further propagation of touch event
return true
end
ball:addEventListener ( “touch”, dragBody )
[/code] [import]uid: 8196 topic_id: 3208 reply_id: 20469[/import]