4/20/2009

AS3 Character Movement: Asteroids Style 360 Degree Movement

Well if we are going to discuss character movement… one of the most important has got to be 360 movement based on rotation. I don’t know if there’s a special name for it, I’ve heard it called everything from 360 degree movement, rotational movement, directional movement, to asteroid style movement. Anyway you want to look at it, it’s a movement style that dates back to arcade games and is definitely a usable option in today’s flash game industry. So how hard is making this angle based movement going to be? Not hard at all.

In most tutorials on this site we start with a blank slate or a very limited one and work our way up. This time, due to the simplicity of this tutorial I’m just going to give you the source code from the start.

Download the the source code here: AS3 Character Movement: Asteroids Style 360 Degree Movement Final Zip Archive

Here’s what our finished tutorial will look like:

Demostration of Flash developing a game with Asteroids style movement. Completely Object Oriented AS3 Code used to develop the ship's movement.

Sweet huh? Let’s get started.

Step 1: Examining the Zip Archive

The contents of the zip are simple. Directionmovement.fla and Ship.as. The fla has two MovieClips, our ship and a shadow MovieClip for our ship. Our ship MovieClip is linked to com.asgamer.directionalmovement.Ship.

Now, there’s something different about this FLA than most on AS Gamer. There is no document class. If you look at the stage in the FLA file you’ll notice the ship is already placed. Because it is already placed on the stage, we don’t have to write a document class to place it. All the code that is linked to our ship will automatically run when the fla is compiled into a swf. Now I wouldn’t make a game this way but for testing and experimenting like we are doing now, it’s perfect.

Next look at our ship MovieClip, you’ll notice it faces towards the right. This is because in flash the 0 rotation starts facing right, 90 faces down, 180 faces left, and 270 faces up (clock-wise). So when we use our geometry functions in Flash (Math.cos, Math.sin, Math.tan2) our results will be based on facing right being the 0 rotation.

Step 2: How we make Rotational Movement.

There’s not a lot to say to preface this step. Just look at the code in Ship.as and I’ll break it down afterwards.

package com.asgamer.directionalmovement
{

import flash.display.MovieClip;
import flash.display.Stage;
import flash.events.Event;
import com.senocular.utils.KeyObject;
import flash.ui.Keyboard;

public class Ship extends MovieClip
{

private var key:KeyObject;
private var speed:Number = 0.3;
private var rotateSpeed:Number = 5;
private var vx:Number = 0;
private var vy:Number = 0;
private var friction:Number = 0.95;

public function Ship () : void
{
key = new KeyObject(stage);
addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
}

public function loop(e:Event) : void
{

if (key.isDown(Keyboard.UP))
{
vy += Math.sin(degreesToRadians(rotation)) * speed;
vx += Math.cos(degreesToRadians(rotation)) * speed;
} else {
vy *= friction;
vx *= friction;
}

if (key.isDown(Keyboard.RIGHT))
rotation += rotateSpeed;
else if (key.isDown(Keyboard.LEFT))
rotation -= rotateSpeed;

y += vy;
x += vx;

if (x > stage.stageWidth)
x = 0;
else if (x < 0)
x = stage.stageWidth;

if (y > stage.stageHeight)
y = 0;
else if (y < 0)
y = stage.stageHeight;
}

public function degreesToRadians(degrees:Number) : Number
{
return degrees * Math.PI / 180;
}

}

}

Okay. Breakdown.

  • imports. The same imports we’ve used at AS Gamer many times before. Nothing special here we just need them so we can access the classes.
  • class vars.
    key:KeyObject -
    instance of Senocular’s KeyObject class that we use for checking Key presses
    speed:Number - the speed our ship increases (when we press UP, as we’ll setup later)
    rotateSpeed:Number - the amount of rotation that occurs (when we press LEFT or RIGHT keys)
    vx and vy - the velocity of our ship in x and y
    friction - causes our ship to gradually stop
  • Constructor Function - in our constructor we setup our key object, which needs to stage passed to it and then we setup and ENTER_FRAME event listener so on every frame we can run the loop function
  • key = new KeyObject(stage); If you’ve kept up with the tutorials on AS Gamer you’ll remember that you can’t fully access the stage in a class outside the document class. In this case we can because our ship is on the stage when the game starts.
  • key.isDown(Keyboard.UP). We simply call isDown in our key class and pass the Keyboard key into the function to see if the key is being pressed. It’s just like AS2.
  • vy += Math.sin(degreesToRadians(rotation)) * speed; - The bread and butter of this script. When UP has been pressed we need to adjust our y velocity based on the direction of our ship. If our rotation is 0 or 180 Math.sin will return 0 so our vy isn’t effected. But if our rotation is 90 or 270 it will return 1 or -1 and therefore fully effected. We do the same with our vx value (except with cosine) to get our results in x.
  • vy *= friction. If UP isn’t being pressed we apply friction to our vy and vx.
  • Then we check if RIGHT or LEFT is being pressed and apply rotation if so.
  • y += vy. Let’s apply our velocity.
  • x > stage.stageWidth. This section just checks if x is off the screen and resets the x to the other side. It does the same for y.
  • degreesToRadians. Last we create our degrees to radians function to convert between the two. Math.sin and Math.cos need a radian value instead of degree to work. So we write this function to do the simple conversion then return us the radian value.

Wow simple huh? Now anytime you move something based on it’s rotation, you know how to do it. If we wanted to make an asteroids game, our ship is almost completely finished. All we’d have to do now is add some asteroids and bullets and we’d be pretty much finished. But this tutorial is about movement… There’s other tutorials on this site that will help you with making the bullets and asteroids.

No comments:

Post a Comment