Radial gravity function?

I was following the guide on how to mimic radial gravity using touch joints found here

https://coronalabs.com/blog/2013/04/09/physics-radial-gravity-and-predicting-trajectory/

I want the object within the raidal field to be attracted to the centre, however I cant quite get it working. (probably because I have no idea what i’m doing…) here is the code I am using

local field = display.newCircle( 0, 0, 100) ; field.alpha = 0.3 field.name = "field" field.x = display.contentCenterX ; field.y = display.contentCenterY physics.addBody( field, "static", { isSensor=true, radius=100 } ) local eggplant = display.newImageRect( scene.perRunGroup, "shapes/monster.png", 45, 45, display.contentCenterX, display.contentCenterY, 30) eggplant.alpha = 1 eggplant.name = eggplant physics.addBody(eggplant, "dynamic", {radius = 20, friction = .4, density = 0.00001, bounce = 0}) eggplant.x = 40 eggplant.y = 0 eggplant.rotation = 0 eggplant.collisionType = "eggplant" function eggplantCollide( self, event ) local otherName = event.other.name local function onDelay( event ) local action = "" if ( action == "makeJoint" ) then self.hasJoint = true self.touchJoint = physics.newJoint( "touch", self, self.x, self.y ) self.touchJoint.frequency = 20 self.touchJoint.dampingRatio = 0.0 self.touchJoint:setTarget( event.other.x, event.other.y ) end end if ( event.phase == "began" and otherName == "field" and self.hasJoint == false ) then local tr = timer.performWithDelay( 10, onDelay ) ; tr.action = "makeJoint" end end

I basically want the eggplant to be attracted the center of the field and the have the touch joint removed after it has left the field.

Have you tried increasing the frequency?

Sure have, hasn’t done anything

Have you tried using physics.setDrawMode(“hybrid”) ?

Unless the code above is not your actual code, I don’t think you’re ever making a touch joint. This will never evaluate as true:

local action = "" if ( action == "makeJoint" ) then

Also, you’re never actually attaching the eggplant collision listener.

Further, you seem to be confusing false with nil. They are not the same value.

Btw, timer.performWithDelay does not return an object - it returns an ID which you can use to reference a timer. But you can’t control the timer directly using the returned value because it’s not an object (though that’s a nice idea.) The timer listener function also doesn’t provide you a parameter value.

I really think you would be better using density values of 1. It just makes the maths come out better at the end of the day, in my experience.

Try this:

local field = display.newCircle( 0, 0, 100) ; field.alpha = 0.3 field.name = "field" field.x = display.contentCenterX ; field.y = display.contentCenterY physics.addBody( field, "static", { isSensor=true, radius=100 } ) local eggplant = display.newCircle( display.contentCenterX-50, display.contentCenterY-200, 45 ) eggplant.alpha = 1 eggplant.name = eggplant physics.addBody(eggplant, "dynamic", {radius = 45, friction = .4, density = 1, bounce = 0}) eggplant.collisionType = "eggplant" function eggplant:collision( event ) local self = event.target local otherName = event.other.name local function onDelay() if (self.action == "makeJoint" ) then self.hasJoint = true self.touchJoint = physics.newJoint( "touch", self, self.x, self.y ) self.touchJoint.frequency = .5 self.touchJoint.dampingRatio = 0 self.touchJoint:setTarget( event.other.x, event.other.y ) self.action = nil end end if ( event.phase == "began" and otherName == "field" and self.hasJoint == nil ) then local tr = timer.performWithDelay( 10, onDelay ) eggplant.action = "makeJoint" end end eggplant:addEventListener( "collision", eggplant )

Cheers man, got that working alright. Now I just need to figure out how to remove the touch joint once it has left the field.

Oh and also, I have a button that removes the eggplant and one that spawns it back it in, however once its been removed and spawned back a touch joint can no longer be created between the field eggplant? Do I have to make the remove button remove the touch joint first? before another one can be created? And how would one do that ? :slight_smile:

Cheers?

When the phase of the collision is “ended”, just remove the touch joint (on a time, of course.)

I suspect you’re not holding the correct reference to the object you’re trying to attach a join to - make sure you are removing the destroyed eggplant object and adding to the new one. Unless you keep a reference to a joint elsewhere, you should be able to destroy the object it is attached to and it will simply disappear. The same is not true for Runtime listeners.

Sorry, but I’m very new, could you do an example? I learn better from examples

Cheers

Have you tried increasing the frequency?

Sure have, hasn’t done anything

Have you tried using physics.setDrawMode(“hybrid”) ?

Unless the code above is not your actual code, I don’t think you’re ever making a touch joint. This will never evaluate as true:

local action = "" if ( action == "makeJoint" ) then

Also, you’re never actually attaching the eggplant collision listener.

Further, you seem to be confusing false with nil. They are not the same value.

Btw, timer.performWithDelay does not return an object - it returns an ID which you can use to reference a timer. But you can’t control the timer directly using the returned value because it’s not an object (though that’s a nice idea.) The timer listener function also doesn’t provide you a parameter value.

I really think you would be better using density values of 1. It just makes the maths come out better at the end of the day, in my experience.

Try this:

local field = display.newCircle( 0, 0, 100) ; field.alpha = 0.3 field.name = "field" field.x = display.contentCenterX ; field.y = display.contentCenterY physics.addBody( field, "static", { isSensor=true, radius=100 } ) local eggplant = display.newCircle( display.contentCenterX-50, display.contentCenterY-200, 45 ) eggplant.alpha = 1 eggplant.name = eggplant physics.addBody(eggplant, "dynamic", {radius = 45, friction = .4, density = 1, bounce = 0}) eggplant.collisionType = "eggplant" function eggplant:collision( event ) local self = event.target local otherName = event.other.name local function onDelay() if (self.action == "makeJoint" ) then self.hasJoint = true self.touchJoint = physics.newJoint( "touch", self, self.x, self.y ) self.touchJoint.frequency = .5 self.touchJoint.dampingRatio = 0 self.touchJoint:setTarget( event.other.x, event.other.y ) self.action = nil end end if ( event.phase == "began" and otherName == "field" and self.hasJoint == nil ) then local tr = timer.performWithDelay( 10, onDelay ) eggplant.action = "makeJoint" end end eggplant:addEventListener( "collision", eggplant )

Cheers man, got that working alright. Now I just need to figure out how to remove the touch joint once it has left the field.

Oh and also, I have a button that removes the eggplant and one that spawns it back it in, however once its been removed and spawned back a touch joint can no longer be created between the field eggplant? Do I have to make the remove button remove the touch joint first? before another one can be created? And how would one do that ? :slight_smile:

Cheers?

When the phase of the collision is “ended”, just remove the touch joint (on a time, of course.)

I suspect you’re not holding the correct reference to the object you’re trying to attach a join to - make sure you are removing the destroyed eggplant object and adding to the new one. Unless you keep a reference to a joint elsewhere, you should be able to destroy the object it is attached to and it will simply disappear. The same is not true for Runtime listeners.

Sorry, but I’m very new, could you do an example? I learn better from examples

Cheers