Decrease speed of object after touch joint is removed

Hi,

I have two dynamic, rotating objects, A and B, that are kept together by a weld joint. The third dynamic object, C, gets connected to A with a touch joint when it comes within a certain distance. This creates the effect that A and B are magnets drawn to C when it is close enough.

When the user moves C “out of range of the magnet”, the touch joint is removed. At this point, I want A and B to stop moving. I have tried setLinearVelocity() with zero values for both x and y but A and B still move. I have also tried setting isBodyActive to false and after a few miliseconds back to true, but then they just start moving again after that.

What am I doing wrong?

Have you tried setting the linearDamping of the object?

It worked like a charm, many thanks @Appletreeman!

Hi @Divergent Monkey,

Can I see your basic code for this? I’m almost sure I can detect the reason when I see how you’re handling things…

Thanks,

Brent

lol, I posted seconds after you did… good to hear you solved it. :slight_smile:

@Brent: Thanks anyway!

@Brent: just out of curiosity, what did you suspect it was? Here is my code:

Creation of the magnet objects (A and B in my original post):

  -- Create visible magnet             local magnet = display.newImageRect("images/magnet.png", 60, 60)             magnet.x = 100             magnet.y = 100             magnet.objectId = properties.objectId.magnet             physics.addBody(magnet, "dynamic", { friction = 0.0, bounce = 0.0, isSensor = true, radius = (magnet.width \* 0.5) })             magnet.gravityScale = 0.0             magnet.collision = onMagnetCollision             magnet:addEventListener("collision", magnet)             sceneGroup:insert(magnet)             -- Create an area in which the magnetic pull is active             local magnetArea = display.newCircle(levelDetails.magnets[i].x, levelDetails.magnets[i].y, 120)             magnetArea.isVisible = false             magnetArea.isHitTestable = true             magnetArea.objectId = properties.objectId.magnetArea             magnetArea.stickyObject = magnet             magnet.stickyObject = magnetArea             physics.addBody(magnetArea, "dynamic", { friction = 0.0, bounce = 0.0, isSensor = true, radius = (magnetArea.width \* 0.5) })             magnetArea.gravityScale = 0.0             sceneGroup:insert(magnetArea)             -- Create a weld joint between the magnet and the magnet area so that they move together             local weldJoint = physics.newJoint("weld", magnet, magnetArea, 0, 0)

In the “began” phase of the collision detection of the other object (C in my original post):

if ((otherObject.isInMagnet == nil) or (otherObject.isInMagnet == false)) then timer.performWithDelay(10, function() otherObject.stickyObject.isInMagnet = true otherObject.stickyObject.touchJointMagnet = physics.newJoint("touch", otherObject.stickyObject, otherObject.x, otherObject.y) otherObject.stickyObject.touchJointMagnet.frequency = 0.30 otherObject.stickyObject.touchJointMagnet.dampingRatio = 1 otherObject.stickyObject.touchJointMagnet:setTarget(spaceship.x, spaceship.y) end) end

In the “ended” phase of the collision detection of the other object (C in my original post):

timer.performWithDelay(10, function() if (otherObject.stickyObject.isInMagnet) then otherObject.stickyObject.isInMagnet = false; otherObject.stickyObject.touchJointMagnet:removeSelf(); otherObject.stickyObject.touchJointMagnet = nil end end, 1)

The “stickyObject”-thing is just to be able to reference A from B and vice versa.

The above code gives the result that A and B still continue to move after the touch joint is removed.

Yeah, your code looks quite good… it’s just, as you already solved, that momentum gained from the touch joint will persist even after the joint is destroyed.

Brent

Ok, thanks!

Have you tried setting the linearDamping of the object?

It worked like a charm, many thanks @Appletreeman!

Hi @Divergent Monkey,

Can I see your basic code for this? I’m almost sure I can detect the reason when I see how you’re handling things…

Thanks,

Brent

lol, I posted seconds after you did… good to hear you solved it. :slight_smile:

@Brent: Thanks anyway!

@Brent: just out of curiosity, what did you suspect it was? Here is my code:

Creation of the magnet objects (A and B in my original post):

  -- Create visible magnet             local magnet = display.newImageRect("images/magnet.png", 60, 60)             magnet.x = 100             magnet.y = 100             magnet.objectId = properties.objectId.magnet             physics.addBody(magnet, "dynamic", { friction = 0.0, bounce = 0.0, isSensor = true, radius = (magnet.width \* 0.5) })             magnet.gravityScale = 0.0             magnet.collision = onMagnetCollision             magnet:addEventListener("collision", magnet)             sceneGroup:insert(magnet)             -- Create an area in which the magnetic pull is active             local magnetArea = display.newCircle(levelDetails.magnets[i].x, levelDetails.magnets[i].y, 120)             magnetArea.isVisible = false             magnetArea.isHitTestable = true             magnetArea.objectId = properties.objectId.magnetArea             magnetArea.stickyObject = magnet             magnet.stickyObject = magnetArea             physics.addBody(magnetArea, "dynamic", { friction = 0.0, bounce = 0.0, isSensor = true, radius = (magnetArea.width \* 0.5) })             magnetArea.gravityScale = 0.0             sceneGroup:insert(magnetArea)             -- Create a weld joint between the magnet and the magnet area so that they move together             local weldJoint = physics.newJoint("weld", magnet, magnetArea, 0, 0)

In the “began” phase of the collision detection of the other object (C in my original post):

if ((otherObject.isInMagnet == nil) or (otherObject.isInMagnet == false)) then timer.performWithDelay(10, function() otherObject.stickyObject.isInMagnet = true otherObject.stickyObject.touchJointMagnet = physics.newJoint("touch", otherObject.stickyObject, otherObject.x, otherObject.y) otherObject.stickyObject.touchJointMagnet.frequency = 0.30 otherObject.stickyObject.touchJointMagnet.dampingRatio = 1 otherObject.stickyObject.touchJointMagnet:setTarget(spaceship.x, spaceship.y) end) end

In the “ended” phase of the collision detection of the other object (C in my original post):

timer.performWithDelay(10, function() if (otherObject.stickyObject.isInMagnet) then otherObject.stickyObject.isInMagnet = false; otherObject.stickyObject.touchJointMagnet:removeSelf(); otherObject.stickyObject.touchJointMagnet = nil end end, 1)

The “stickyObject”-thing is just to be able to reference A from B and vice versa.

The above code gives the result that A and B still continue to move after the touch joint is removed.

Yeah, your code looks quite good… it’s just, as you already solved, that momentum gained from the touch joint will persist even after the joint is destroyed.

Brent

Ok, thanks!