Coding Bullets with Acceleration

General discussion about LÖVE, Lua, game development, puns, and unicorns.
Post Reply
User avatar
Gunroar:Cannon()
Party member
Posts: 1088
Joined: Thu Dec 10, 2020 1:57 am

Coding Bullets with Acceleration

Post 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.
The risk I took was calculated,
but man, am I bad at math.

-How to be saved and born again :huh:
User avatar
BrotSagtMist
Party member
Posts: 613
Joined: Fri Aug 06, 2021 10:30 pm

Re: Coding Bullets with Acceleration

Post 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.
obey
User avatar
darkfrei
Party member
Posts: 1179
Joined: Sat Feb 08, 2020 11:09 pm

Re: Coding Bullets with Acceleration

Post 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 3607 times
:awesome: in Lua we Löve
:awesome: Platformer Guide
:awesome: freebies
User avatar
pgimeno
Party member
Posts: 3550
Joined: Sun Oct 18, 2015 2:58 pm

Re: Coding Bullets with Acceleration

Post by pgimeno »

Velocity depends on acceleration, not the other way around.
User avatar
Gunroar:Cannon()
Party member
Posts: 1088
Joined: Thu Dec 10, 2020 1:57 am

Re: Coding Bullets with Acceleration

Post 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.
The risk I took was calculated,
but man, am I bad at math.

-How to be saved and born again :huh:
User avatar
BrotSagtMist
Party member
Posts: 613
Joined: Fri Aug 06, 2021 10:30 pm

Re: Coding Bullets with Acceleration

Post 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
obey
User avatar
knorke
Party member
Posts: 239
Joined: Wed Jul 14, 2010 7:06 pm
Contact:

Re: Coding Bullets with Acceleration

Post 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
User avatar
darkfrei
Party member
Posts: 1179
Joined: Sat Feb 08, 2020 11:09 pm

Re: Coding Bullets with Acceleration

Post by darkfrei »

Just get it in recommendations:
:awesome: in Lua we Löve
:awesome: Platformer Guide
:awesome: freebies
Post Reply

Who is online

Users browsing this forum: No registered users and 224 guests