@martinlim520
I see some problems with your code and I’ll provide some answers too. Bear with me:
Problems:
- Forces are not applied once. You usually apply them every frame in an enterFrame listener. (If you’re looking for a ‘kick’ use and impulse instead, or set the linear velocity.
- Calling get/set linear velocity is OK in an enterFrame listener, but it may be a bit excessive and interfere with the natural/calculated behavior of the physics engine. That said it is OK, just be careful.
- If you are setting velocities in ‘enterFrame’, at some point, the velocity will be so low it will essentially be zero. You should set a cut-off point and manually treat values below that (absolute) value as zero.
- In none of your calculations are you taking into account mass. This will be fine unless you decide to make a physics object bigger or smaller, then all your hard work will go out the window because the objects will behave differently. I always multiply forces by the objects’ masses (obj.mass) to get consistent behavior even if I later change the size of an object.
Answers:
- Your code is pretty good, but could be improved as noted above (I’ll show an improvement in a moment).
- The easiest way to slow an object down is via linearDamping.
Suggestion:
local ball2 = display.newCircle(150,400,20) physics.addBody(ball2,"dynamic") ball2.linearDamping = 0.5 -- make higher to slow down faster ball2:applyLinearImpulse(10 \* ball2.mass, -10 \* ball2.mass, ball2.x,ball2.y) -- or maybe something like this: --ball:setLinearVelocity( 100, -100 ) local function gameLoop() local vx,vy = ball2:getLinearVelocity() if( vx == 0 and vy == 0) then return end vx = (math.abs(vx) \< 0.005) and 0 or (vx \* 0.6) vy = (math.abs(vy) \< 0.005) and 0 or (vy \* 0.6) ball2:setLinearVelocity(vx,vy) end Runtime:addEventListener("enterFrame", gameLoop )