Love.physics: Shooting objects towards the mouse pos?
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
-
- Prole
- Posts: 5
- Joined: Mon Dec 05, 2011 7:29 pm
Love.physics: Shooting objects towards the mouse pos?
Hello everyone!
I have been trying to figure out this problem to make an object shoot towards the mouse's X and Y coordinates using both applyForce() and applyImpulse(), but since math and physics aren't not my strongest subjects I've failed to do so. How would you go about this using one of these functions?
I have been trying to figure out this problem to make an object shoot towards the mouse's X and Y coordinates using both applyForce() and applyImpulse(), but since math and physics aren't not my strongest subjects I've failed to do so. How would you go about this using one of these functions?
-
- Prole
- Posts: 12
- Joined: Sat Dec 24, 2011 6:03 pm
Re: Love.physics: Shooting objects towards the mouse pos?
Actually, you don't need to use love.physics to do that. It can be done with some trig. Basically what you do is found out the angle between the origin of the object and the mouse position. You form a right triangle from that and the hypotenuse will be the speed of your moving object. I'll provide a more detailed response later today when I have more time to
Re: Love.physics: Shooting objects towards the mouse pos?
What you need to do is:
1.convert the mouse cursor to physics world coordinates
where mx and my is the mouse cursor position
scale measures how many pixels equal 1 meter in box2d
ox and oy are offsets from the center of the camera/world
2.find the vector between the mouse cursor (in world coords) and the body's position
where bx and by are the body's position
3.normalize the vector and multiply it by the impulse magnitude
4.apply the impulse vector to the body (at its position)
applyForce is used when you want to continually apply a force to a body throughout several frames
1.convert the mouse cursor to physics world coordinates
Code: Select all
wmx, wmy = mx * scale + ox, my * scale + oy
scale measures how many pixels equal 1 meter in box2d
ox and oy are offsets from the center of the camera/world
2.find the vector between the mouse cursor (in world coords) and the body's position
Code: Select all
dx, dy = bx - wmx, by - wmy
3.normalize the vector and multiply it by the impulse magnitude
Code: Select all
d = math.sqrt ( dx * dx + dy * dy )
ndx, ndx = dx / d, dy / d
impulse = 300
ix, iy = ndx * impulse, ndy * impulse
Code: Select all
body:applyImpulse ( ix, iy, bx, by )
-
- Prole
- Posts: 12
- Joined: Sat Dec 24, 2011 6:03 pm
Re: Love.physics: Shooting objects towards the mouse pos?
PurpleDrain, I wrote a tutorial on how to fire a bullet toward the mouse position. You can find it here. I hope it's helpful and if you have any questions please feel free to ask them.
Re: Love.physics: Shooting objects towards the mouse pos?
Ivans method is better. Because it's faster.
-
- Prole
- Posts: 12
- Joined: Sat Dec 24, 2011 6:03 pm
Re: Love.physics: Shooting objects towards the mouse pos?
Thanks for that info. I didn't know that. Could you explain why it's faster? I'm curious as to all things LOVE.vrld wrote:Ivans method is better. Because it's faster.
Re: Love.physics: Shooting objects towards the mouse pos?
Well, with target.x, target.y denoting the target position (i.e. mouse) and pos.x, pos.y denoting the objects position, your code boils down to:
That's two subtractions and two multiplications, which are done in practically no time, but three calls to relatively expensive trigonometric functions, math.atan, math.cos and math.sin.
Ivans method is based on vectors:
I.e. one sum, two subtractions, four multiplications, and two divisions (all of which are pretty fast) and only one more expensive call to math.sqrt.
Benchmarking both approaches against each other:
Yields (results may vary):
So you can see that excluding the boilerplate code, the vector approach is about 50% faster than the trigonometry one.
In the end it probably doesn't matter, but I for one prefer to work with vectors. Interestingly both methods are equivalent (see here).
Edit: code correction (atan2)
Code: Select all
local angle = math.atan2(target.y - pos.y, target.x - pos.x)
local dx = math.cos(angle) * speed
local dy = math.sin(angle) * speed
Ivans method is based on vectors:
Code: Select all
local dx = target.x - pos.x
local dy = target.y - pos.y
local len = math.sqrt(dx*dx + dy*dy)
dx = dx/len * speed -- can be packed into len
dy = dy/len * speed
Benchmarking both approaches against each other:
Code: Select all
function trig(target, pos, speed)
local angle = math.atan2(target.y - pos.y, target.x - pos.x)
local dx = math.cos(angle) * speed
local dy = math.sin(angle) * speed
return dx,dy
end
function vectors(target, pos, speed)
local dx = target.x - pos.x
local dy = target.y - pos.y
local len = math.sqrt(dx*dx + dy*dy)
dx = dx/len * speed
dy = dy/len * speed
return dx,dy
end
function nothing() end
function profile(func, iterations)
math.randomseed(1) -- to get the same numbers
local start = os.clock()
for i=1,iterations do
local target = {x = (math.random()*2 - 1) * 100, y = (math.random()*2 - 1) * 100}
local pos = {x = (math.random()*2 - 1) * 100, y = (math.random()*2 - 1) * 100}
func(target, pos, math.random() * 10 + 5)
end
return os.clock() - start
end
Code: Select all
> print("time:", profile(nothing, 1000000) )
time: 3.14
> print("time:", profile(trig, 1000000) )
time: 4.78
> print("time:", profile(vectors, 1000000) )
time: 3.97
> print("relative time:", (profile(vectors, 1000000) - profile(nothing, 1000000)) / (profile(trig, 1000000) - profile(nothing, 1000000)) )
relative time: 0.49056603773585
In the end it probably doesn't matter, but I for one prefer to work with vectors. Interestingly both methods are equivalent (see here).
Edit: code correction (atan2)
Last edited by vrld on Mon Dec 26, 2011 11:36 am, edited 1 time in total.
-
- Prole
- Posts: 12
- Joined: Sat Dec 24, 2011 6:03 pm
Re: Love.physics: Shooting objects towards the mouse pos?
Thanks for the reply vrld. So doesn't that mean that if you manually coded in the vector math rather than using love.physics it would go eve faster (because it wouldn't deal with anything else that the love.physics call did)? I'll update my tutorial on the wiki to use vectors tomorrow.
Re: Love.physics: Shooting objects towards the mouse pos?
Hi again.
Yes, vrld is correct however the difference in performance would be practically unnoticeable in most cases.
Also:
Shouldn't it be:
I never though about it about it but you're right:
Would be another optimization.
Yes, vrld is correct however the difference in performance would be practically unnoticeable in most cases.
Also:
Code: Select all
local angle = math.atan(target.y - pos.y, target.y - pos.y)
Code: Select all
local angle = math.atan2(target.y - pos.y, target.y - pos.y)
Code: Select all
local len = math.sqrt(dx*dx + dy*dy)
dx = dx/len * speed -- can be packed into len
dy = dy/len * speed
Code: Select all
local len = 1/math.sqrt(dx*dx + dy*dy)*speed
dx = dx * len
dy = dy * len
-
- Prole
- Posts: 12
- Joined: Sat Dec 24, 2011 6:03 pm
Re: Love.physics: Shooting objects towards the mouse pos?
Thanks everyone for the clarifications and explanation. I'll be sure to update the tutorial tomorrow using this new stuff that I've learned.
Keep on being awesome
Keep on being awesome
Who is online
Users browsing this forum: Bing [Bot] and 6 guests