The first thing you must understand is the concepts of acceleration vs. velocity. The way I think of it is that velocity is the rate that the object is traveling. While the acceleration is the rate that the object is changing it's velocity.
Their actual definitions are as follows:
- Acceleration = Velocity / Time
- Velocity = Distance / Time
So an object traveling with a velocity of 2 ft/sec will travel 4 feet in 2 seconds. Likewise, an object with an initial velocity of 2 ft/sec and an acceleration of 2 ft/sec^2 (feet per second per second) will have a velocity of 6 ft/sec after two seconds.
Now let's apply that to Asteroids, everyone's favorite game:
Now we know three things: The player's velocity x/y components, acceleration, and direction. These will be known from now on as Vx/Vy, A, and Theta respectively.
Every frame in the game we will need to do the following:
- Set the acceleration if the accelerate key is pressed
- Figure out the X-Y components of the acceleration
- Update the player's velocity X-Y components based on the acceleration X-Y components
- Update the player's position with the Velocity X-Y components
So first thing's first, we will have to figure out x-y components. You can see from the picture above that any vector quantity (a direction and magnitude) can be broken up into it's horizontal and vertical components. Using the basic trigonometry trio, SOHCAHTOA, we can find the missing parts of the imaginary right triangle we created with our player's angle:
To break up acceleration:
A,X = A * COS(THETA)
A,Y = A * SIN(THETA)
Now that you've got your components, you can add the acceleration components to the velocity components:
V,X += A,X
V,Y += A,Y
And then finally update the player's position based on the velocity components:
X += V,X
Y += V,Y
There you go, basic asteroid physics!
Here is some code written in BlitzMax, you should be able to adapt the code to any language:
Graphics 800,600
Type TShip
Field x:Float,y:Float
Field vx:Float, vy:Float
Field ax:Float, ay:Float
Field Direction:Float
Method Init()
x = 400
y = 300
End Method
Method Update()
Local Acceleration:Float
If KeyDown(KEY_UP)
Acceleration=.2
Else
Acceleration=0
End If
If KeyDown(KEY_LEFT)
Direction:-2
End If
If KeyDown(KEY_RIGHT)
Direction:+2
End If
Local ax:Float = Acceleration * Cos(Direction)
Local ay:Float = Acceleration * Sin(Direction)
vx:+ax
vy:+ay
x:+vx
y:+vy
If x < 0 x = 800
If x > 800 x = 0
If y < 0 y = 600
If y > 600 y = 0
End Method
Method Draw()
DrawLine x-Cos(Direction)*10,y-Sin(Direction)*10,x+Cos(Direction)*10,y+Sin(Direction)*10
End Method
End Type
Local MyShip:TShip = New TShip
MyShip.Init
While Not KeyHit(KEY_ESCAPE)
Cls
MyShip.Update()
MyShip.Draw()
Flip 1
EndWhile
End
Here is some code written in BlitzMax, you should be able to adapt the code to any language:
Graphics 800,600
Type TShip
Field x:Float,y:Float
Field vx:Float, vy:Float
Field ax:Float, ay:Float
Field Direction:Float
Method Init()
x = 400
y = 300
End Method
Method Update()
Local Acceleration:Float
If KeyDown(KEY_UP)
Acceleration=.2
Else
Acceleration=0
End If
If KeyDown(KEY_LEFT)
Direction:-2
End If
If KeyDown(KEY_RIGHT)
Direction:+2
End If
Local ax:Float = Acceleration * Cos(Direction)
Local ay:Float = Acceleration * Sin(Direction)
vx:+ax
vy:+ay
x:+vx
y:+vy
If x < 0 x = 800
If x > 800 x = 0
If y < 0 y = 600
If y > 600 y = 0
End Method
Method Draw()
DrawLine x-Cos(Direction)*10,y-Sin(Direction)*10,x+Cos(Direction)*10,y+Sin(Direction)*10
End Method
End Type
Local MyShip:TShip = New TShip
MyShip.Init
While Not KeyHit(KEY_ESCAPE)
Cls
MyShip.Update()
MyShip.Draw()
Flip 1
EndWhile
End
No comments:
Post a Comment