[SOLVED] Math + Spread bullets
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
[SOLVED] Math + Spread bullets
Hi everyone, I'm back here with a little issue with my "spread bullets".
So here is the deal, I try to make some firing (like a shotgun) and spread alls bullets randomly.
My actual result is not spreading like how it should with my rotate gun.
So if any one got a tips in how to realise this trick ?
Thanks in advance.
So here is the deal, I try to make some firing (like a shotgun) and spread alls bullets randomly.
My actual result is not spreading like how it should with my rotate gun.
So if any one got a tips in how to realise this trick ?
Thanks in advance.
Last edited by var77 on Fri Jul 12, 2019 3:35 pm, edited 1 time in total.
Re: Math + Spread bullets
ps: files if it's also help
(sorry to post that in a reply buts seems buggy when I post multiple attachement stuff)Re: Math + Spread bullets
currently it seems you're spawning the bullets with an offset, while what it seems you want is the spawn at the same point and adjust the velocity
So first decide at what distance you want the set of bullets to look like the shape you have in mind. let's call this distance D
Then, for each bullet with xoffst, yoffst offset from the center of target the shape X, Y (s.t. X, Y is the point in the direction of the shot, at a distance of D), you know the location you want it to be at at time t=D/speed. namely, X+xoffst, y+yoffst Then its a simple matter of calculating the velocity that gets it there - basically the vector connecting the shooter to the bullet's destination divided by t.
I'd suggest making a function that calculates all the velocities for you given a set of offsets and target distance, which you can run at initialization on all the shapes you have in mind to get a 'shot' configuration for every shot type you want.
So first decide at what distance you want the set of bullets to look like the shape you have in mind. let's call this distance D
Then, for each bullet with xoffst, yoffst offset from the center of target the shape X, Y (s.t. X, Y is the point in the direction of the shot, at a distance of D), you know the location you want it to be at at time t=D/speed. namely, X+xoffst, y+yoffst Then its a simple matter of calculating the velocity that gets it there - basically the vector connecting the shooter to the bullet's destination divided by t.
I'd suggest making a function that calculates all the velocities for you given a set of offsets and target distance, which you can run at initialization on all the shapes you have in mind to get a 'shot' configuration for every shot type you want.
Re: Math + Spread bullets
something like this will work
NOTE. I did not look at your code so I don't know how you actually set up your projectiles so it may need to be modified a bit to make it work as desired
now add your velocity to your position every frame with dt multiplied in and it should work
NOTE. I did not look at your code so I don't know how you actually set up your projectiles so it may need to be modified a bit to make it work as desired
Code: Select all
function setBulletVelocity(bullet)
-- first get direction you want to shoot in radians and a speed
speed = 200
direction = 0 -- this will need to be set to whatever direction you want to fire
-- than add in some random spread
direction = direction + math.rad(math.random(-50,50)/100) -- I divided by 100 to make this number small
-- now set the velocity vector for your projectile
bullet.velocity[0] = math.cos(direction )*speed
bullet.velocity[1] = math.sin(direction )*speed
end
Code: Select all
function projectileUpdate(projectile,dt)
projectile.position[0] = projectile.position[0] + projectile.velocity[0] * dt
projectile.position[1] = projectile.position[1] + projectile.velocity[1] * dt
end
Re: Math + Spread bullets
First of all thanks both a you for aswering me I think I see my issue more clearly.
So I got to add some "offsetX/Y" or "VelocityX/Y" to my projectile to get this effect,
with an other function that will spread my result (position X/Y).
But I guess I don't handle how in my case.
I create my projectile like this:
Then I update position like this:
If I following you well I have to add a random "offsetX/Y" or "VelocityX/Y" in:
What I exactly don't understand is how I get this "offsetX/Y" or "VelocityX/Y"
with my moving angle getting from my mouse ? or what is the function ?
sorry not that good in math
So I got to add some "offsetX/Y" or "VelocityX/Y" to my projectile to get this effect,
with an other function that will spread my result (position X/Y).
But I guess I don't handle how in my case.
I create my projectile like this:
Code: Select all
local startX = visor.x + (visor.w / 24)
local startY = visor.y + (visor.h / 24)
-- angle rotation that depend of my mouse position --
local angle = math.atan2((mouse.y - startY), (mouse.x - startX))
local bulletDx = visor.speed*2 * math.cos(angle) -- destination X
local bulletDy = visor.speed*2 * math.sin(angle) -- destination Y
local size = 3.45
table.insert(b, {x = startX, y = startY, dx = bulletDx, dy = bulletDy,r=size})
table.insert(b, {x = startX, y = startY, dx = bulletDx, dy = bulletDy,r=size})
table.insert(b, {x = startX, y = startY, dx = bulletDx, dy = bulletDy,r=size})
Then I update position like this:
Code: Select all
if #bullets1 > 0 then
for i,v in ipairs(bullets1) do
v.x = v.x + (v.dx * t)
v.y = v.y + (v.dy * t)
if v.x < 0 or v.x > gameWidth or v.y < 0 or v.y > gameHeight then
table.remove(bullets1, i) -- if projectile are out from the screen remove them
end
end
if #bullets1 < 1 then user.shoot1 = false end
end
Code: Select all
v.x = v.x + (v.dx * t)
v.y = v.y + (v.dy * t)
--like this
v.x = v.x + (v.dx +v.velocityX * t)
v.y = v.y + (v.dy +v.velocityY * t)
with my moving angle getting from my mouse ? or what is the function ?
sorry not that good in math
Re: Math + Spread bullets
Wouldn't it suffice to randomize the angle a bit? Something like this:var77 wrote: ↑Wed Jul 10, 2019 8:40 pm I create my projectile like this:
Code: Select all
... local bulletDx = visor.speed*2 * math.cos(angle) -- destination X local bulletDy = visor.speed*2 * math.sin(angle) -- destination Y ...
Code: Select all
angle = angle + love.math.random() * bulletSpreadAngle - bulletSpreadAngle/2
local bulletDx = visor.speed*2 * math.cos(angle) -- destination X
local bulletDy = visor.speed*2 * math.sin(angle) -- destination Y
Code: Select all
local bulletSpreadAngle = math.rad(5) -- 5 degrees spread
Re: Math + Spread bullets
If you don't want any specific shape you can just add love.math.random() * spread_factor to `angle` to get the angle for the bullet, as pgimeno explained.
Since I saw you were adding/subtracting specific (non-random) amounts from the bullet's position in your code:
I thought you might want the bullets to form a particular shape, in which case you'll want to set their velocities by deciding what relative position each bullet should have at some (in principle any) time T and setting the amount that puts them there.
Since I saw you were adding/subtracting specific (non-random) amounts from the bullet's position in your code:
Code: Select all
table.insert(b, {x = startX, y = startY, dx = bulletDx, dy = bulletDy,r=size})
table.insert(b, {x = startX-15, y = startY+15, dx = bulletDx, dy = bulletDy,r=size})
table.insert(b, {x = startX-20, y = startY+20, dx = bulletDx, dy = bulletDy,r=size})
table.insert(b, {x = startX-25, y = startY-20, dx = bulletDx, dy = bulletDy,r=size})
table.insert(b, {x = startX-35, y = startY-30, dx = bulletDx, dy = bulletDy,r=size})
table.insert(b, {x = startX-45, y = startY-40, dx = bulletDx, dy = bulletDy,r=size})
Code: Select all
local D = 200 -- number is up to you, play around with it, smaller number means bigger spread
local T = D / visor.speed*2 -- the time it will take to get there
local angle = math.atan2((mouse.y - startY), (mouse.x - startX))
local shape_center_x = D * math.cos(angle)
local shape_center_y = D * math.sin(angle)
...
-- create the individual bullets
local xoffst, yoffst
xoffst = 0 -- choose numbers for each bullet to make your shape
yoffst = 0
table.insert(b, {x=startX, y=startY,
dx=((shape_center_x + xoffst) - shape_center_x) / T,
dy=((shape_center_y + yoffst) - shape_center_y) / T,
r=size}
xoffst = -15
yoffst = +15
table.insert(b, {x=startX, y=startY,
dx=((shape_center_x + xoffst) - shape_center_x) / T,
dy=((shape_center_y + yoffst) - shape_center_y) / T,
r=size}
...
-- and so on
Re: Math + Spread bullets
First thanks again all of you. Both aproach gave interesting result.
After post my last reply I found what I was searching with just adding
two var that I may have to random:
Even if @pgimeno make a random start spread, what I was looking for is
closer from @TheHUG method. Control the shape of the spread was not that
expected but it make it more efficient in my release.
Unfortunatly after testing your code I guess something went wrong
with this: dx = ((shape_center_x + xoffset)-shape_center_x)/T
For me this is like: dx = xoffset/T if I'm right.
And the result is that it spread only on the left side
(and don't mind about the rotate angle).
So I change it for: dx = (shape_center_x + xoffset)/T and
it fit better but close to my last found. And here is the point.
It spread large on top of screen but line it on side of screen.
so if you got any idea why ? I guess I have to play with
additional var from startX/Y (like x = startX-15, y = startY+15)
it gave me few interesting result.
After post my last reply I found what I was searching with just adding
two var that I may have to random:
Code: Select all
table.insert(b, {x = startX, y = startY, dx = bulletDx, dy = bulletDy,r=size,vx=15,vy=15})
-- and
v.x = v.x + ((v.dx+v.vx) * t)
v.y = v.y + ((v.dy+v.vy) * t)
Even if @pgimeno make a random start spread, what I was looking for is
closer from @TheHUG method. Control the shape of the spread was not that
expected but it make it more efficient in my release.
Unfortunatly after testing your code I guess something went wrong
with this: dx = ((shape_center_x + xoffset)-shape_center_x)/T
For me this is like: dx = xoffset/T if I'm right.
And the result is that it spread only on the left side
(and don't mind about the rotate angle).
So I change it for: dx = (shape_center_x + xoffset)/T and
it fit better but close to my last found. And here is the point.
It spread large on top of screen but line it on side of screen.
so if you got any idea why ? I guess I have to play with
additional var from startX/Y (like x = startX-15, y = startY+15)
it gave me few interesting result.
Re: Math + Spread bullets
Why make things easier when you can complex them... I finaly found
exactly the expected result. Sorry @pgimeno you were right (as often
with my issues) just need to add some math.rad() to the angle like this for example:
nevermind thanks all for your answers, good to explore many method.
exactly the expected result. Sorry @pgimeno you were right (as often
with my issues) just need to add some math.rad() to the angle like this for example:
Code: Select all
table.insert(b, {x = startX, y = startY, dx = visor.speed * math.cos(angle+math.rad(1)), dy = visor.speed * math.sin(angle+math.rad(1)),r=size})
Re: Math + Spread bullets
Oops, quite silly of me, it was supposed to be:var77 wrote: ↑Thu Jul 11, 2019 4:44 pm First thanks again all of you. Both aproach gave interesting result.
After post my last reply I found what I was searching with just adding
two var that I may have to random:
Code: Select all
table.insert(b, {x = startX, y = startY, dx = bulletDx, dy = bulletDy,r=size,vx=15,vy=15}) -- and v.x = v.x + ((v.dx+v.vx) * t) v.y = v.y + ((v.dy+v.vy) * t)
Even if @pgimeno make a random start spread, what I was looking for is
closer from @TheHUG method. Control the shape of the spread was not that
expected but it make it more efficient in my release.
Unfortunatly after testing your code I guess something went wrong
with this: dx = ((shape_center_x + xoffset)-shape_center_x)/T
For me this is like: dx = xoffset/T if I'm right.
And the result is that it spread only on the left side
(and don't mind about the rotate angle).
So I change it for: dx = (shape_center_x + xoffset)/T and
it fit better but close to my last found. And here is the point.
It spread large on top of screen but line it on side of screen.
spread_firering2.png
so if you got any idea why ? I guess I have to play with
additional var from startX/Y (like x = startX-15, y = startY+15)
it gave me few interesting result.
dx = ((shape_center_x + xoffst) - start_X)
and I forgot to consider that you might want to rotate the shape by angle. But if pgimeno's solutions does what you want there's no reason to add complexity.
Who is online
Users browsing this forum: Ahrefs [Bot], Bing [Bot], Google [Bot] and 4 guests