Pages

Friday, February 10, 2012

Asteroids movement physics

One of the fundamental ways to visualize basic frictionless motion is through an asteroids game.

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:

  1. Acceleration = Velocity / Time
  2. 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:
  1. Set the acceleration if the accelerate key is pressed
  2. Figure out the X-Y components of the acceleration
  3. Update the player's velocity X-Y components based on the acceleration X-Y components
  4. 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

No comments:

Post a Comment