How do i move an object to another with physics?

So this is what i need. 

So i tap on the screen and a box spawns and it moves to the circle which can be anywhere in the screen…

I know i could use transition.to but then physics don’t apply.

I can use setLinearVelocity but the circle moves and the boxes can be spawned anywhere on the screen.

Thanks!

–SonicX278

roughly:

local dx,dy = circle.x-box.x, circle.y-box.y -- calc the delta local ix,iy = dx\*magic,dy\*magic -- scale delta by tuned "magic value" as impulse box:applyLinearImpulse(ix,iy,box.x,box.y) -- apply the impulse (alt: applyForce)

Alternatively, try a touch joint. May not be what you’re looking for, but it’s the “accepted” way to move physics objects to a point.

https://docs.coronalabs.com/guide/physics/physicsJoints/index.html#touch

  • Caleb

I’m trying to shoot bullet at a moving object… But the enemy is always moving…

so a “guided missile” scenario?  do you allow your ai to “cheat” (know things about the target’s state that aren’t externally observable) or not?  there are a range of approaches from can-cheat-game-quality to can’t-cheat-military-quality – what’s your need and background?  (fe, if i used a term like “derivative” would you follow?  at least familiar with basic linear algebra?)

Here is sample. 

local physics = require("physics") physics.start() local bullet = {} local bCounter = 1 local circleOne = display.newCircle( display.contentCenterX, display.contentCenterY, 30 ) physics.addBody( circleOne, "dynamic" ) circleOne.gravityScale = 0 local box = display.newRect( display.contentCenterX, display.contentCenterY - 200, 20, 20 ) local function shoot(event) bullet[bCounter] = display.newCircle( box.x, box.y, 10 ) physics.addBody( bullet[bCounter], "dynamic" ) bullet[bCounter].gravityScale = 0 bullet[bCounter].value = bCounter bCounter = bCounter + 1 end local function startAndEnd(event) if event.phase == "began" then timerStart = timer.performWithDelay( 100, shoot, -1 ) elseif event.phase == "ended" then timer.cancel( timerStart ) end end box:addEventListener( "touch", startAndEnd ) local function moveBox( event ) box.x = event.x box.y = event.y end box:addEventListener( "touch", moveBox )

What i want is so the balls that are spawned fly at the circle even if the circle is moving.

–SonicX278

Ok. So you won’t be using a touch joint, then (obviously).

For a basic approach, you can find the difference between the positions of the two objects, then set velocity based on that, or for more complexity, you can find the difference, calculate the normal, and launch based on that (it’ll result in uniform speed), or for even more complexity, Google “projectile interception” and come up with something from that.

  • Caleb

Here’s a simple implementation:

local physics = require("physics") physics.start() local bullet = {} local bCounter = 1 local circleOne = display.newCircle( display.contentCenterX, display.contentCenterY, 30 ) physics.addBody( circleOne, "dynamic" ) circleOne.gravityScale = 0 local box = display.newRect( display.contentCenterX, display.contentCenterY  - 200, 20, 20 ) local speedMultiplier = 50 local function shoot(event)         bullet[bCounter] = display.newCircle( box.x, box.y, 10 )         physics.addBody( bullet[bCounter], "dynamic" )         bullet[bCounter].gravityScale = 0         bullet[bCounter].value = bCounter       -- METHOD 1: Simple          -- local diffX, diffY = circleOne.x - bullet[bCounter].x, circleOne.y - bullet[bCounter].y     -- bullet[bCounter]:setLinearVelocity(diffX \* speedMultiplier, diffY \* speedMultiplier)          -- METHOD 2: Slightly more complex - this is probably better because bullets will fire at a constant speed     local diffX, diffY = circleOne.x - bullet[bCounter].x, circleOne.y - bullet[bCounter].y     local distance = ((diffX \* diffX) + (diffY \* diffY)) ^ 0.5     local normalX, normalY = diffX / distance, diffY / distance     bullet[bCounter]:setLinearVelocity(normalX \* speedMultiplier, normalY \* speedMultiplier)          -- METHOD 3: Nah... Implement it yourself. Bleh. Really quite complex.          bCounter = bCounter + 1 end local function startAndEnd(event)     if event.phase == "began" then         timerStart = timer.performWithDelay( 100, shoot, -1 )     elseif event.phase == "ended" then         timer.cancel( timerStart )     end end box:addEventListener( "touch", startAndEnd ) local function moveBox( event )     box.x = event.x     box.y = event.y end box:addEventListener( "touch", moveBox )
  • Caleb

Thanks Caleb! I actually had the first method but i love the second one!

–SonicX278

as per Caleb (fwiw, equivalent:  Caleb’s 1) == my magic=50; Caleb’s 2) == my magic=50/distance)

for a first baby step along 3… divide distance to target by expected bullet velocity, this gives time-to-target.  now when calculating deltas, first apply target’s time-scaled velocity to its position.  (perhaps you’ll allow your bullet to “cheat” just a little and pretend that it has witnessed several positions to derive velocity)  that will “predict” where target will be (to a first approximation) by the time bullet reaches it.  this is what human shooters do to “lead the target” (but oh so much more)

roughly:

local dx,dy = circle.x-box.x, circle.y-box.y -- calc the delta local ix,iy = dx\*magic,dy\*magic -- scale delta by tuned "magic value" as impulse box:applyLinearImpulse(ix,iy,box.x,box.y) -- apply the impulse (alt: applyForce)

Alternatively, try a touch joint. May not be what you’re looking for, but it’s the “accepted” way to move physics objects to a point.

https://docs.coronalabs.com/guide/physics/physicsJoints/index.html#touch

  • Caleb

I’m trying to shoot bullet at a moving object… But the enemy is always moving…

so a “guided missile” scenario?  do you allow your ai to “cheat” (know things about the target’s state that aren’t externally observable) or not?  there are a range of approaches from can-cheat-game-quality to can’t-cheat-military-quality – what’s your need and background?  (fe, if i used a term like “derivative” would you follow?  at least familiar with basic linear algebra?)

Here is sample. 

local physics = require("physics") physics.start() local bullet = {} local bCounter = 1 local circleOne = display.newCircle( display.contentCenterX, display.contentCenterY, 30 ) physics.addBody( circleOne, "dynamic" ) circleOne.gravityScale = 0 local box = display.newRect( display.contentCenterX, display.contentCenterY - 200, 20, 20 ) local function shoot(event) bullet[bCounter] = display.newCircle( box.x, box.y, 10 ) physics.addBody( bullet[bCounter], "dynamic" ) bullet[bCounter].gravityScale = 0 bullet[bCounter].value = bCounter bCounter = bCounter + 1 end local function startAndEnd(event) if event.phase == "began" then timerStart = timer.performWithDelay( 100, shoot, -1 ) elseif event.phase == "ended" then timer.cancel( timerStart ) end end box:addEventListener( "touch", startAndEnd ) local function moveBox( event ) box.x = event.x box.y = event.y end box:addEventListener( "touch", moveBox )

What i want is so the balls that are spawned fly at the circle even if the circle is moving.

–SonicX278

Ok. So you won’t be using a touch joint, then (obviously).

For a basic approach, you can find the difference between the positions of the two objects, then set velocity based on that, or for more complexity, you can find the difference, calculate the normal, and launch based on that (it’ll result in uniform speed), or for even more complexity, Google “projectile interception” and come up with something from that.

  • Caleb

Here’s a simple implementation:

local physics = require("physics") physics.start() local bullet = {} local bCounter = 1 local circleOne = display.newCircle( display.contentCenterX, display.contentCenterY, 30 ) physics.addBody( circleOne, "dynamic" ) circleOne.gravityScale = 0 local box = display.newRect( display.contentCenterX, display.contentCenterY  - 200, 20, 20 ) local speedMultiplier = 50 local function shoot(event)         bullet[bCounter] = display.newCircle( box.x, box.y, 10 )         physics.addBody( bullet[bCounter], "dynamic" )         bullet[bCounter].gravityScale = 0         bullet[bCounter].value = bCounter       -- METHOD 1: Simple          -- local diffX, diffY = circleOne.x - bullet[bCounter].x, circleOne.y - bullet[bCounter].y     -- bullet[bCounter]:setLinearVelocity(diffX \* speedMultiplier, diffY \* speedMultiplier)          -- METHOD 2: Slightly more complex - this is probably better because bullets will fire at a constant speed     local diffX, diffY = circleOne.x - bullet[bCounter].x, circleOne.y - bullet[bCounter].y     local distance = ((diffX \* diffX) + (diffY \* diffY)) ^ 0.5     local normalX, normalY = diffX / distance, diffY / distance     bullet[bCounter]:setLinearVelocity(normalX \* speedMultiplier, normalY \* speedMultiplier)          -- METHOD 3: Nah... Implement it yourself. Bleh. Really quite complex.          bCounter = bCounter + 1 end local function startAndEnd(event)     if event.phase == "began" then         timerStart = timer.performWithDelay( 100, shoot, -1 )     elseif event.phase == "ended" then         timer.cancel( timerStart )     end end box:addEventListener( "touch", startAndEnd ) local function moveBox( event )     box.x = event.x     box.y = event.y end box:addEventListener( "touch", moveBox )
  • Caleb

Thanks Caleb! I actually had the first method but i love the second one!

–SonicX278

as per Caleb (fwiw, equivalent:  Caleb’s 1) == my magic=50; Caleb’s 2) == my magic=50/distance)

for a first baby step along 3… divide distance to target by expected bullet velocity, this gives time-to-target.  now when calculating deltas, first apply target’s time-scaled velocity to its position.  (perhaps you’ll allow your bullet to “cheat” just a little and pretend that it has witnessed several positions to derive velocity)  that will “predict” where target will be (to a first approximation) by the time bullet reaches it.  this is what human shooters do to “lead the target” (but oh so much more)