2D Game Physics - Part II - Acceleration

- benjamin805 benjamin805

Object Acceleration

We will now look at how you can add acceleration to your game objects. It's very easy to do and should not take much programming on your part. An example of when acceleration is needed could be when driving a car, flying a ship, rolling down hill, etc.

Acceleration is something that affects an objects speed and can be added to the speed or subtracted from it. Imagine a car speeding up or slowing down, or a rocket ship flying through space or coming to a stop. In the examples here we will be working with racing cars. Four racing cars will take off from the starting line and race to the finish line. Their acceleration will increase as they move forward or as the drivers step on the gas pedal.

We will make a change to our sub setangle by adding acceleration to it. We will also change our speed variable to be byref so that our sub can change this value.
sub setangle byref velocity.x, byref velocity.y,angle,byref speed,acceleration
 
speed=speed+acceleration  'we now add in the acceleration
 
r.angle=angle/57.29577951
 
scale.x=cos(r.angle)
scale.y=sin(r.angle)
 
velocity.x=speed*scale.x
velocity.y=speed*scale.y
 
end sub
 
 

Setup acceleration starting values

So the first part of setting up our example is to setup the cars starting positions and direction. I put this in a gosub since we will call it each time a race starts. We will set the starting speeds for each car to zero since they will increase with the acceleration value. Each cars acceleration will be chosen randomly so you will not know the winner until you press go!
[carsetup]
car1.x=20
car1.y=300
car1.vx=0 ' velocity.x
car1.vy=0 ' velocity.y
car1.speed=0
 
car2.x=20
car2.y=330
car2.vx=0 ' velocity.x
car2.vy=0 ' velocity.y
car2.speed=0
 
car3.x=20
car3.y=360
car3.vx=0 ' velocity.x
car3.vy=0 ' velocity.y
car3.speed=0
 
car4.x=20
car4.y=390
car4.vx=0 ' velocity.x
car4.vy=0 ' velocity.y
car4.speed=0
 
'get random acceleration value, we do not want any cars to have the same
' value
'we also do not want to use the int value for this example.
 
[doover]
car1.a=rnd(1)*1 'acceleration for car 1
car2.a=rnd(1)*1 'acceleration for car 2
if car2.a=car1.a then [doover]
car3.a=rnd(1)*1 'acceleration for car 3
if car3.a=car1.a or car3.a=car2.a then [doover]
car4.a=rnd(1)*1 'acceleration for car 4
if car4.a=car1.a or car4.a=car2.a or car4.a=car3.a then [doover]
 
 
'draw cars at starting position
#main "cls"
#main "color red;line ";car1.x;" ";car1.y;" ";car1.x+10;" ";car1.y
#main "color blue;line ";car2.x;" ";car2.y;" ";car2.x+10;" ";car2.y
#main "color green;line ";car3.x;" ";car3.y;" ";car3.x+10;" ";car3.y
#main "color brown;line ";car4.x;" ";car4.y;" ";car4.x+10;" ";car4.y
return
 
 

Increasing acceleration

When the race starts we will increase the acceleration of each car by recalling our setangle sub over and over. What this does is increases the speed of each car by adding more acceleration to the speed value with each call. Take a look at the game loop.
[move]
'increase each cars acceleration
call setangle car1.vx,car1.vy,angle,car1.speed,car1.a
call setangle car2.vx,car2.vy,angle,car2.speed,car2.a
call setangle car3.vx,car3.vy,angle,car3.speed,car3.a
call setangle car4.vx,car4.vy,angle,car4.speed,car4.a
 
'move cars
car1.x=car1.x+car1.vx   'increase object.x value
car1.y=car1.y-car1.vy
if car1.x>finishline then
    timer 0
    notice "Red car won!"
    wait
end if
 
car2.x=car2.x+car2.vx   'increase object.x value
car2.y=car2.y-car2.vy
if car2.x>finishline then
    timer 0
    notice "Blue car won!"
    wait
end if
 
car3.x=car3.x+car3.vx   'increase object.x value
car3.y=car3.y-car3.vy
if car3.x>finishline then
    timer 0
    notice "Green car won!"
    wait
end if
 
car4.x=car4.x+car4.vx   'increase object.x value
car4.y=car4.y-car4.vy
if car4.x>finishline then
    timer 0
    notice "Brown car won!"
    wait
end if
 
'draw cars
#main "cls"
#main "color red;line ";car1.x;" ";car1.y;" ";car1.x+10;" ";car1.y
#main "color blue;line ";car2.x;" ";car2.y;" ";car2.x+10;" ";car2.y
#main "color green;line ";car3.x;" ";car3.y;" ";car3.x+10;" ";car3.y
#main "color brown;line ";car4.x;" ";car4.y;" ";car4.x+10;" ";car4.y
wait
 
 

Start the race!

When all the new code is in place we can start the race! Here is a complete listing for the example program.
'2D Game Physics - Part II
nomainwin
 
WindowWidth=800
WindowHeight=600
 
button #main,"Go!",[go],ul,10,10,35,30
 
open "2D Game Physics - Part II" for graphics_nsb as #main
#main "trapclose [quit]"
#main "size 20;down"
 
 
 
finishline=750
angle=0
 
gosub [carsetup]
 
wait
 
 
[go]
gosub [carsetup]
timer 100,[move]
wait
 
 
[move]
call setangle car1.vx,car1.vy,angle,car1.speed,car1.a
call setangle car2.vx,car2.vy,angle,car2.speed,car2.a
call setangle car3.vx,car3.vy,angle,car3.speed,car3.a
call setangle car4.vx,car4.vy,angle,car4.speed,car4.a
 
car1.x=car1.x+car1.vx   'increase object.x value
car1.y=car1.y-car1.vy
if car1.x>finishline then
    timer 0
    notice "Red car won!"
    wait
end if
 
car2.x=car2.x+car2.vx   'increase object.x value
car2.y=car2.y-car2.vy
if car2.x>finishline then
    timer 0
    notice "Blue car won!"
    wait
end if
 
car3.x=car3.x+car3.vx   'increase object.x value
car3.y=car3.y-car3.vy
if car3.x>finishline then
    timer 0
    notice "Green car won!"
    wait
end if
 
car4.x=car4.x+car4.vx   'increase object.x value
car4.y=car4.y-car4.vy
if car4.x>finishline then
    timer 0
    notice "Brown car won!"
    wait
end if
 
'draw object
#main "cls"
#main "color red;line ";car1.x;" ";car1.y;" ";car1.x+10;" ";car1.y
#main "color blue;line ";car2.x;" ";car2.y;" ";car2.x+10;" ";car2.y
#main "color green;line ";car3.x;" ";car3.y;" ";car3.x+10;" ";car3.y
#main "color brown;line ";car4.x;" ";car4.y;" ";car4.x+10;" ";car4.y
wait
 
[carsetup]
car1.x=20
car1.y=300
car1.vx=0 '
car1.vy=0 '
car1.speed=0
 
car2.x=20
car2.y=330
car2.vx=0 '
car2.vy=0 '
car2.speed=0
 
car3.x=20
car3.y=360
car3.vx=0 '
car3.vy=0 '
car3.speed=0
 
car4.x=20
car4.y=390
car4.vx=0 '
car4.vy=0 '
car4.speed=0
 
[doover]
car1.a=rnd(1)*1 'acceleration for car 1
car2.a=rnd(1)*1 'acceleration for car 2
if car2.a=car1.a then [doover]
car3.a=rnd(1)*1 'acceleration for car 3
if car3.a=car1.a or car3.a=car2.a then [doover]
car4.a=rnd(1)*1 'acceleration for car 4
if car4.a=car1.a or car4.a=car2.a or car4.a=car3.a then [doover]
 
 
'draw cars at starting position
#main "cls"
#main "color red;line ";car1.x;" ";car1.y;" ";car1.x+10;" ";car1.y
#main "color blue;line ";car2.x;" ";car2.y;" ";car2.x+10;" ";car2.y
#main "color green;line ";car3.x;" ";car3.y;" ";car3.x+10;" ";car3.y
#main "color brown;line ";car4.x;" ";car4.y;" ";car4.x+10;" ";car4.y
return
 
[quit]
timer 0
close #main
end
 
sub setangle byref velocity.x, byref velocity.y,angle,byref speed,acceleration
 
speed=speed+acceleration  'we now add in the acceleration
 
r.angle=angle/57.29577951
 
scale.x=cos(r.angle)
scale.y=sin(r.angle)
 
velocity.x=speed*scale.x
velocity.y=speed*scale.y
 
end sub