ActionScript.org Flash, Flex and ActionScript Resources - http://www.actionscript.org/resources
Car Movement
http://www.actionscript.org/resources/articles/648/1/Car-Movement/Page1.html
Philip Peralov
Philip is a Flash guru and a ActionScript freak. He has done a couple of projects, featuring games, programs, websites & cartoons. He's only 15 years old, but he well knows programing in Java & ActionScript and is a professional in Animating. In his free time he goes to the local High School :) in Bitola, Macedonia, Europe, where he lives.
 
By Philip Peralov
Published on August 7, 2007
 
Time: 45 minutes
Requirements: Flash 8
Description:
In this tutorial I'll show you how to make a simple car driving game, where the user can drive the car, accelerate, brake, etc. Also will teach you the basics of the Drawing API by ActionScripting the trail that leaves the car.


Overview & Graphics
So, in this tutorial you'll learn how to create a simple car movement game, something like this one:

First you need to do is to find some little car picture with view from top like this:



Insert that car in Flash and make it a MovieClip. Type car at the Instance Name of the symbol.



So that's it with the graphics. Now comes the ActionScript. We'll mainly learn the usage of the following things:
  • if staitments
  • Key.isDown
  • Math.sin & Mat.cos
  • Drawing API
  • Other (createEmptyMovieClip, swapDepths, _rotation...)
Now, let's start ActionScripting...

Basic
Almost the whole script will be put in the car, so select the car symbol and open the ActionScript window. The first thing we need to do is to set a variable called speed, with a default value of 0. Let's do that.
[as]onClipEvent (load) {
var speed:Number = new Number (0);
}[/as]
Now, that the speed variable is set, we can add script for increasing that variable. We don't want to raise the speed to one number (ex. 20), so we're going to make it increase slowly.
[as]onClipEvent (enterFrame) {
if (Key.isDown (Key.UP)) {
speed += 1.5;
}
}[/as]
What this script does is increasing the speed for value of 1.5 every timeline frame if the UP arrow key is down. The if staitment checks to see if the condition in the brackets is true. For example: If the frame rate is set to 20 fps and the UP arrow key is down, then the speed will raise to value of 30 (20*1.5=30).
Now if you left the UP key, the car speed will stop increasing, but it won't decrease either. So you can edit the script to get:
[as]onClipEvent (enterFrame) {
if (Key.isDown (Key.UP)) {
speed += 1.5;
}
speed = speed * 0.98;
}[/as]
This script is decreasing the speed by multiplying it with 0.98, that means the speed will get to 98% of the previous speed.
In order to move the car right and left we need to put _rotation scripts. And if we want to go backward, we also need a script for that. Put them all under the enterFrame event:
[as]if (Key.isDown (Key.DOWN)) {
speed -= 0.8;
}
if (Key.isDown (Key.RIGHT)) {
_rotation += 8;
}
if (Key.isDown (Key.LEFT)) {
_rotation -= 8;
}[/as]
Now, to get the car move. Because the car can rotate, we need to know at what direction is turned. The easiest way to do that is by using the math sine and cosine, in Flash known as Math.sin & Math.cos. With those we can calculate the angle of the car position.
[as]_x += Math.sin (_rotation * Math.PI / 180) * speed;
_y += Math.cos (_rotation * Math.PI / 180) * -speed;[/as]
You also need to put this under the enterFrame event. What Math.PI/180 does is it's convert the degrees (in this case _rotation) to radians (used for calculating sine and cosine. Then the sine and cosine are multiplied with the speed, so the car goes to the right direction.
We forgot something. The car has an unlimited speed. Not with this script:
[as]if (Math.abs (speed) > 20) {
speed = 20;
}
if (speed < -10) {
speed = -10;
}[/as]
The first script limits the forward speed to a value of 20 and the second limits the backword to a value of 10.
And you can finally put a brake in the car, by simply adding the following script:
[as]if (Key.isDown (Key.CONTROL)) {
speed -= speed / 10;
}[/as]I'm sure you can already guess what the script does. But wait! When holding the UP arrow key and the CTRL key together they keep fighting. And the UP arrow wins! So, find the script where is the UP arrow key script called and change the script to this.
[as]if (Key.isDown (Key.UP) & !Key.isDown (Key.CONTROL)) {
speed += 1.5;
}[/as]
What this script does is that it checks: is CTRL key NOT down. That's why the "!" is there. That means NOT.

So the basics are done. The car can accelerate, move right and left, go backward and even break! But what about little bugs, like rotating without even moving? And it wouldn't look nicer if it lefts wheel trail? See on the next page.

*All the previous scripts except the var speed:Number = new Number (0); script belongs to the onClipEvent (enterFrame) handler.

What's Wrong?
So we the little game so far, but, something is wrong. First we need to analyze the errors and then - fix them. Bugs, errors or just unfinished work :) I couldn't think of another than these:
  1. Why the car can spin when it doesn't have speed?
  2. In reality using the handbrake while turning causes car spinning.
  3. Is it possible the car to lefts a wheel trail?
  4. In reality....there are millions of  laws. So think of one and try to recopy it in ActionScript yourself :)
Why the car can spin when it doesn't have speed?
Well you know why, because no one wrote a script for not to do that. So the car doesn't brakes any laws. Because those laws don't exist. But if we make those laws good enough, without any holes, the car will never break them.

Now, modify the RIGHT key script to something like this:
[as]if (Key.isDown (Key.RIGHT)) {
    if (speed < 5 && speed >= 0) {
        _rotation += 2 * speed;
    } if (speed < 0) {
        _rotation += 7.5 * speed / 15;
    } else {
        _rotation += 7.5;
    }
    speed *= 0.95;
}[/as]
What it does is firs it checks if the speed is lower than value of 5 and higher or equal to 0. If that statement is true then the rotation of the car depends on the speed. And that means lower speed lower rotation. No speed, no rotation. The value of 5 is taken because I tested and it looks fine. Sometimes testing is better than calculating. The speed<0 condition is for backward turning. Again the values are get by testing. Add the same script to the LEFT key, just change the + into -.

In reality using the handbrake while turning causes car spinning.
That's why the following script is used for. Modify the CTRL key script like this:
[as]if (Key.isDown (Key.CONTROL)) {
    speed -= speed / 10;
    if (Key.isDown (Key.RIGHT)) {
        _rotation += speed / 2;
    }
    if (Key.isDown (Key.LEFT)) {
        _rotation -= speed / 2;
    }
}[/as]
Like usual first it checks to see if the CTRL key is down, then if the RIGHT key is down it spins to right. The same is with the left. Variable speed is used so the rotation can stop when the speed is 0. Simply, isn't?

Is it possible the car to lefts a wheel trail?
Yeah. It's possible! For that will use the Drawing API. There is a bit of ActionScript so see on the next page.

In reality....there are millions of  laws.
Right. And you can always recopy (try to recopy) them to flash. You can always add more and more stuff. But if you want to finish your project, the best is to get a final picture and stick to it.

See the next page for the wheel trail.

Wheel Trails
Now, we'll program the car, so it can left a trail on the ground, made by the wheels. For that purpose we'll use the Drawing API. The drawing API allows you to draw lines and shapes with ActionScript and gives you the freedom to start an application with the computer equivalent of a blank canvas, on which you can create whatever images you wish. We need to know what we want to do with the drawing API.

In this case we want to make a wheel trail. So, we're going to use the car _x and _y properties to draw those lines. First we'll try to draw just one line from the center of the car. So let's start.

All the scripts goes to the car mc (short term for MovieClip). Create a mc for the drawing (we use mc instead the stage to draw, because like this we can change the depth property).
[as]onClipEvent (load) {
    var speed:Number = new Number (0);
    _root.createEmptyMovieClip ("drawing",1);
    this.swapDepths (_root.drawing);
}[/as]
The new empty mc it's called "drawingMC" and it has a depth value of 1. We use swapDepths to make the car over the trail. Otherwise the car can (will) be under them.

Now under the enterFrame event add the following script:
[as]_root.drawing.lineStyle (3,0xeeeeee,100);
    _root.drawing.lineTo (_x,_y);[/as]
Yeah, it works nice, but at the start the lines start from 0,0 coordinates. Fix that by applying this script under the onLoad event.
[as]_root.drawing.moveTo (_x,_y);[/as]

Next, we need to move the trail to the left or the right so it will looks like it's coming from one of the tires. We can't just use _x+2 or something like that, because the car rotates and the values need to change. That's why under the enterFrame event enter:
[as]xTrail = Math.sin (_rotation * Math.PI / 180) * 10;
yTrail = Math.cos (_rotation * Math.PI / 180) * 10;
xTrailCalculated = _x - yTrail;
yTrailCalculated = _y - xTrail;[/as]
I'm not going to explain this script, because we already discussed this on page 2.

However, we're not going to remove the recently script _root.drawing.moveTo (_x,_y); and we're going to add something similar to the enterFrame event because when we gonna add another trail those two will get together.

Modify the script to something like this.
[as]xTrailCalculated = _x - yTrail;
yTrailCalculated = _y - xTrail;
xTrailCalculated2 = _x + yTrail;
yTrailCalculated2 = _y + xTrail;
_root.drawing.moveTo (xTrailCalculated,yTrailCalculated);
_root.drawing.lineTo (_x - yTrail,_y - xTrail);
_root.drawing.moveTo (xTrailCalculated2,yTrailCalculated2);
_root.drawing.lineTo (_x + yTrail,_y + xTrail);[/as]
All we need to do now is to add the following script to the onLoad event and we're done.
[as]xTrail = Math.sin (_rotation * Math.PI / 180) * 10;
yTrail = Math.cos (_rotation * Math.PI / 180) * 10;
xTrailCalculated = _x - yTrail;
yTrailCalculated = _y - xTrail;
xTrailCalculated2 = _x + yTrail;
yTrailCalculated2 = _y + xTrail;[/as]
We applied the same script to the onLoad event because otherwise the lines will begin with coordinates of 0, 0, and we sure don't want that :) And if you want to apply stronger trail when the car brakes, think a litlle yourself......It's easy.

The source file and this tutorial in .pdf are in attachments