Page 1 of 1

Coding Bullets with Acceleration

Posted: Fri Jul 22, 2022 11:39 am
by Gunroar:Cannon()
I'm trying to figure out how to code better bullets, which I noticed after observing some gameplay of Nuclear Throne, build up velocity and don't move at their fastest immediately. Now I add an acceleration value like this

Code: Select all

init()
    ...
    --ac = acceleration
    self.vx = math.cos(angle)
    self.vy = -1*math.sin(angle)
    self.ax = self.ac*self.vx
    self.ay = self.ac*self.vy
    ...
end

update(dt)
    ...
    self.vx = self.vx+self.ax*dt
    self.vy = self.vy+self.ay*dt
    ...
end
That works okay (though not too well :rofl: should I use tweening...?) The main problem I'm having is how I can do something like a bullet that takes a while to accelerate but accelerates fast (like a missile). If I make the ac slow the bullet just moves slowly, and if the ac is high it just moves fast.

Re: Coding Bullets with Acceleration

Posted: Fri Jul 22, 2022 12:25 pm
by BrotSagtMist
If your bullet has two different speeds you need to describe it using two different functions, one getting smaller over time, one limits to the final speed, for example:
speed=(T/(T+x1)*F1)+((1-T/(T+x2))*F2)
Where T is time and F is a speedvalue of choice and x is for adjustment.
In the first part, when T starts at zero it we get the speed multiplied with 0/x=0, but when we grow the value x can be neglected and T/T=1 thus we will end up at full speed F1 over time.
The second function inverts this by starting at 1 and negating the mechanism.
If we add booth we can describe one smooth transition between two speeds. Finding the right values is up to you tho.

Re: Coding Bullets with Acceleration

Posted: Fri Jul 22, 2022 12:51 pm
by darkfrei
Let's use the math!

If you are need the speed, that changes by the time, the simplest solution will be just have internal timer and it will be rising by the time. But after some time the speed must be constant, not change anymore:
(x is time and y is speed)
https://www.desmos.com/calculator/imqojwlj60
2022-07-22T14_02_40-Desmos _ Grafik-Rechner.png
2022-07-22T14_02_40-Desmos _ Grafik-Rechner.png (18.14 KiB) Viewed 3984 times

Re: Coding Bullets with Acceleration

Posted: Fri Jul 22, 2022 12:54 pm
by pgimeno
Velocity depends on acceleration, not the other way around.

Re: Coding Bullets with Acceleration

Posted: Fri Jul 22, 2022 9:56 pm
by Gunroar:Cannon()
darkfrei wrote: Fri Jul 22, 2022 12:51 pm Let's use the math!

If you are need the speed, that changes by the time, the simplest solution will be just have internal timer and it will be rising by the time. But after some time the speed must be constant, not change anymore:
(x is time and y is speed)
https://www.desmos.com/calculator/imqojwlj60
2022-07-22T14_02_40-Desmos _ Grafik-Rechner.png
Ahh, it might be the easiest but not the most ...modular if that makes sense (not being tweaked by values easily). Tweening ...I might be wrong (I also don't want to give each bullet a tweening class cause I think it affects performance though I doubt that). I guess I'll try it :cry:
pgimeno wrote: Fri Jul 22, 2022 12:54 pm Velocity depends on acceleration, not the other way around.
I multiplied ac by vx and vy so that it would be in the right direction (since they were just representing directions) which was dumb beat-around-the-bush coding on my part but if you look closely that doesn't actually do anything so acceleration is still affecting velocity, not depending on it.
BrotSagtMist wrote: Fri Jul 22, 2022 12:25 pm If your bullet has two different speeds you need to describe it using two different functions, one getting smaller over time, one limits to the final speed, for example:
speed=(T/(T+x1)*F1)+((1-T/(T+x2))*F2)
Where T is time and F is a speedvalue of choice and x is for adjustment.
In the first part, when T starts at zero it we get the speed multiplied with 0/x=0, but when we grow the value x can be neglected and T/T=1 thus we will end up at full speed F1 over time.
The second function inverts this by starting at 1 and negating the mechanism.
If we add booth we can describe one smooth transition between two speeds. Finding the right values is up to you tho.

I really wish this worked but I couldn't get it...
I did something like this

Code: Select all

update(dt)
    self.t = math.min((self.t or 0)+dt,1)
    local f1  = self.ac --say...200
    local f2 = 10
    local x1 = 1
    local x2 = 1
    local t = self.t
    
    self.vx = (t/(t+x1)*f1)+((1-t/(t+x2))*f2)
    ...
Though the speed just seemed the same even when fiddling with x1,x2 and the Fs.

Re: Coding Bullets with Acceleration

Posted: Fri Jul 22, 2022 11:30 pm
by BrotSagtMist
That was just a lame untested example.
You need to be more creative, fiddle with the values AND the function, add more values, add exponents.
There is no easy route to that, adjusting timings simply is a pita.

Code: Select all

T=0
F1=20000
F2=200
X=10
Y=300
x1=10
love.draw=function()
 love.graphics.circle("fill",X,Y,10)
end
love.update=function(dt)
 T=T+dt
 X=X+dt*((T^10/(T^10+x1)*F1)+F2)
end

Re: Coding Bullets with Acceleration

Posted: Fri Jul 22, 2022 11:57 pm
by knorke
let's ignore the deltatime dt stuff for a moment and also only deal with speed in x-coordinate.
every physic frame the position changes by a certain amount. This difference between old and new position is called speed.
also known as:

Code: Select all

x=x+xspeed
What happens if xspeed is not constant, but also changes every time? The difference between old and new speed is called acceleration.
also known as:

Code: Select all

xspeed=xspeed+xacc
x=x+xspeed
example:

Code: Select all

local x,y,xspeed,xacc = 0,0,0,0,0,0
local traces={}

function shoot()
    x=0
    y=40
    xspeed=0
    xacc=200
    xspeedmax=1000
    traces = {}
end

function love.load()
    shoot()
end

local t = 0
function love.update(dt)
    x=x+(xspeed*dt)
    xspeed=xspeed+(xacc*dt)
    if xspeed>xspeedmax then xspeed=xspeedmax end    

    ---    
    if x > 800 then y = y + 50 x=0 end
    if y > 400 then shoot () end
    t=t+dt 
    if t > 0.1 then traces[#traces+1] = {x=x,y=y} t=0 end 
end
    
function love.draw()
    love.graphics.circle("fill",x, y, 20)
	love.graphics.print("xspeed:"..xspeed, 100, 300)
	for i,v in ipairs(traces) do
        love.graphics.circle("line",traces[i].x, traces[i].y, 20)    
    end

 end
1) Try different values in shoot() function.
2) Try setting a high startspeed and negative acceleration.
3) Now what really moves the hamsterball is when the acceleration also changes. The difference between old acceleration and new acceleration is called jerk.
also known as:

Code: Select all

xacc=xacc+xjerk
xspeed=xspeed+xacc
x=x+xspeed

Re: Coding Bullets with Acceleration

Posted: Sat Jul 23, 2022 9:46 pm
by darkfrei
Just get it in recommendations: