Tutorials Home | Simple Ship

In this tutorial, you will learn how to create a simple spaceship in Flash, like the file shown here (at left). You will create two functions and use simple trigonometry to calculate the direction, acceleration, and position of the ship on the stage.

You will also be attaching the ship dynamically from the library, and learning how to set the linkage options for attaching library symbols at runtime. And, hopefully, you will have fun!

This tutorial is ActionScript (AS) 2.0, characterized by strict typing of variables and the use of dot-notation to reference the ship object.

This tutorial could be expanded further along those lines into a class-based file, where you create a 'Ship' class and import the ship MovieClip from the library as a Ship Object.


Simple Ship Tutorial (Beginner)

1. Create a new Flash Document

Change the properties of the document to 500x500 pixels and give it a black background.

2. Draw your ship on the Stage

Draw a ship graphic directly on the Stage, using the Flash vector drawing tools. The pen tool works good for this. You can make it however detailed you like, but make sure the ship is pointing directly toward the right, otherwise it will not appear to fly straight. This is very important.

3. Convert your ship to a MovieClip

Select the entire graphic you just created, and press F8 (Convert to Symbol) to create a MovieClip, and name it 'mcShip'. Make sure the registration point is in the center of the ship. Now, you should see a MovieClip symbol in the library window named 'mcShip'. (If the library window is not open, open it by selecting Window->Library in Flash 8.) Right-click on mcShip and select the 'Linkage...' option from the menu. Check the 'Export for ActionScript' checkbox and give it the identifier 'ship'.

4. Add a thruster graphic

Edit the library symbol by double-clicking on mcShip in the library. Add a new layer and name it 'actions'. Click on frame 1 of the 'actions' layer, then open the actions window and type stop(); in the actions window. Now re-name the original layer to 'ship', and click on frame 2 of the 'ship' layer and press F6 to create a new keyframe. The new keyframe should contain the ship graphic that was on frame 1. Add a thruster graphic to the ship graphic on the new keyframe.

5. Add ActionScript

Now exit the mcShip MovieClip and re-name the layer on the main timeline to 'actions' and delete any content on that keyframe. Then add the following code to the keyframe (it should be your only keyframe):

//Simple Ship
//an example of a simple Asteroids engine...
//presented by www.IndieFlashArcade.com

//key listener
Key.addListener(this);

//define constants
var nRotationSpeed:Number = 15;
var nThrust:Number = 0.8;
var nConversion:Number = Math.PI / 180;

//define variables
var xVelocity:Number = 0;
var yVelocity:Number = 0;

//attach ship from library and create a reference variable
var mcShip:MovieClip = attachMovie("ship","mcShip",0);

//position ship on the stage
mcShip._x = Stage.width / 2;
mcShip._y = Stage.height / 2;

this.onEnterFrame = shipControls;

function shipControls():Void {

  //ship rotation
  if(Key.isDown(Key.LEFT))
  {
      mcShip._rotation -= nRotationSpeed;
  }
  else if(Key.isDown(Key.RIGHT))
  {
      mcShip._rotation += nRotationSpeed;
  }

  //ship thrust
  if(Key.isDown(Key.UP))
  {
      var nRadians:Number = mcShip._rotation * nConversion;
      var xAcceleration:Number = Math.cos(nRadians) * nThrust;
      var yAcceleration:Number = Math.sin(nRadians) * nThrust;
      xVelocity += xAcceleration;
      yVelocity += yAcceleration;
      mcShip.gotoAndStop(2);
  }
  else
  {
      mcShip.gotoAndStop(1);
  }

  //move the ship
  mcShip._x += xVelocity;
  mcShip._y += yVelocity;

  shipBounds();

}

function shipBounds():Void {

  //test stage boundaries, wrap to screen
  if(mcShip._x - (mcShip._width / 2) > Stage.width)
  {
      mcShip._x = (-(mcShip._width / 2));
  }
  else if(mcShip._x < 0 - (mcShip._width / 2))
  {
      mcShip._x = Stage.width + (mcShip._width / 2);
  }
  if(mcShip._y > Stage.height + (mcShip._height / 2))
  {
      mcShip._y = (-(mcShip._height / 2));
  }
  else if(mcShip._y < 0 - (mcShip._height / 2))
  {
      mcShip._y = Stage.height + (mcShip._height / 2);
  }

}

stop();

Now let's examine some of the code that makes the ship move. Fist we define some constant values that do not change (nRotation, nThrust, and nConversion), and our velocity variables, xVelocity and yVelocity. Next, we attach the ship from the library using the attachMovie() method, and we position the ship in the center of the stage. Pretty easy so far.

In order to animate the ship, we will need to make some calculations on each frame, and to do this we will use the onEnterFrame handler. This event (enter frame) happens every time the Flash Player advances one frame, which is determined by the movie's frame rate (in frames per second). Even if you have only one frame, and you include a stop(); command, the onEnterFrame event will happen at the movie's frame rate.

In this case, we are assigning a separate function (shipControls) as the onEnterFrame handler for the root MovieClip. The .swf movie itself is treated just like a MovieClip, which means it has all of the methods that a MovieClip has, and also the same events, such as onEnterFrame. Thus, the Flash Player will execute the function shipControls() on every frame, allowing us to calculate our ship's flight across the screen.

The contents of the handler function are simply two if() else statements, and some updating to the ship's _x and _y properties. The if() else statements are used to determine what keys the user is pressing. Making them separate allows us to test for combinations of keys, such as up and left, while not allowing other combinations, such as left and right. We use the Key.isDown() function to determine which key is being held down, if any. The left and right keys affect the _rotation property of our ship (which will be used for calculating it's velocity). Obviously, the right key adds rotation value (clockwise), and the left one lowers it (counterclockwise).

The next part is where the math comes in, and right away we use the _rotation property of the ship and convert it to a radian value, nRadians. This is done using the constant that we declared earlier, nConversion, which is the formula for converting degrees to radians. The reason for this is because the sin() and cos() functions expect radian values, and the _rotation is a degree value. Another constant, nThrust, is used to determine the acceleration on the x and y axes, and is stored in the xAcceleration and yAcceleration variables. Essentially, this is force that propels the ship forward, and the cosine and sine functions determine the right amount of force to add in each direction (x, y). The acceleration is then added to the velocity, effectively speeding up the ship. The gotoAndStop() command is used to show and hide the thruster graphic, by switching frames on the mcShip MovieClip.

Finally, we get to the most important lines of code, the ones that actually make the ship move! The x and y velocity values are added to the _x and _y values for the ship, making it appear to move across the screen, in the direction that it's pointing.

After that is a function call to shipBounds(), which simply tests the ship against the edges of the screen, as defined in the shipBounds() function. It uses the same mutually exclusive logic that was used above: that the ship cannot be colliding with both the top and the bottom of the screen at the same time (just as the user cannot press the left and right key at the same time); however, the ship can be colliding with the top and left sides of the screen. Thus, we use two separate if() else statements: one for top and bottom, the other for left and right. When a collision with the edge is detected, the ship is positioned on the opposite side of the screen.

As you can see, this example is fairly limited in what it can do; however one immediate improvement would be the addition of friction. If you put the following code just above the code that moves your ship, you will get friction:

xVelocity = xVelocity * .95;
yVelocity = yVelocity * .95;

© Indie Flash Arcade .com

Tutorials Home | Simple Ship