ivan wrote: ↑Fri Dec 08, 2017 3:46 pm
If you want to change the velocity using impulses then:
changeInVelocity = finalVelocity - initialVelocity
impulse = mass*changeInVelocity
Apply the impulse only once to achieve the DESIRED velocity.
The "desired" velocity should remain constant unless one of the following is involved:
1.gravity 2.collisions 3.linear damping 4.joints.
If you want to maintain a constant velocity over time, then use ApplyForce.
setLinearVelocity is not recommended for dynamic bodies, because it overrides the effects of "collision responses" and doesn't look realistic.
Thank you for your reply, this helped a lot, although it took me a while to get my head around this. Indeed, it makes more sense to calculate the correct vector in before-hand, instead of correcting the vector with additional forces afterwards.
First of all, I didn't know that any impulses respecting the mass of my body, but this makes sense. I couldn't see this effect when changing my mass, because I was setting the mass before creating fixtures for my body. After creating the fixtures it changed my mass.
So to sum it up with my own words:
- I get the linear velocity of my body
- I multiply my power with my direction and subtract the current linear velocity from it
- I multiply the result with the mass of the body
- The result is the force that will move my object the same distance without respecting mass and ignoring initial velocity <- this gonna be applied as impulse
- since the initial velocity of my object needs to be multiplied by the mass to get enough counter force on the impulse, I have to multiply the mass to it, always
For the community, here is my solution: An update function code to shoot an object in the direction of my mouse click without respecting mass and ignoring initial velocity. (setMass will be called at the end of the enter function, canShot will be set true on ground collision, power is pre-configured):
Code: Select all
if love.mouse.isDown(1) and canShot and not releasedShot then
canShot = false
releasedShot = true
local clickVector = Vector(love.mouse:getX(), love.mouse:getY())
local bulletPosVector = Vector(body:getX(), body:getY())
local bulletVelVector = Vector(body:getLinearVelocity())
local distVector = (clickVector - bulletPosVector)
local dirVector = distVector:normalized()
body:applyLinearImpulse(body:getMass() * (power * dirVector.x - bulletVelVector.x), body:getMass() * (power * dirVector.y - bulletVelVector.y))
body:applyAngularImpulse(dirVector.x * power, dirVector.y * power) -- rotation can stay wild!!!
elseif canShot and releasedShot and not love.mouse.isDown(1) then
releasedShot = false
end
(for easier presentation I removed architecture relevant parts, of course I don't work with global variables in this case)
Any suggestions? I'm new to this and I appreciate any feedback to improve myself.
ivan wrote: ↑Fri Dec 08, 2017 3:46 pm
I recommend:
Code: Select all
--- Clamp length
-- @param v vector
-- @param d maximum length
-- @return initial length of the vector
function clamp(v, d)
local x, y = v.x, v.y
local d2 = math.sqrt(x*x + y*y)
if d2 > d then
v.x = x/d2*d
v.y = y/d2*d
end
return d2
end
I've to admit, I don't get the exact use for this function. Can you explain further?