Building a Simple Driving Game with ActionScript 3.0

Jul 10th in Games by Stephen Cronin

In this tutorial I'll be going through the steps needed to build a simple driving program. You'll learn how to add keyListeners, eventListeners and a couple of other things using ActionScript 3.0. I originally wrote this program in ActionScript 2.0 and in this tutorial I'll compare the two ActionScript versions as we go along. This should therefore make for an easy tutorial to start moving your way over to ActionScript 3.0.

PG

Author: Stephen Cronin

Hey! My name is Stephen and I am a high school student from Boston. Over the years I have taught myself Flash/AS, HTML, and have mastered Illustrator and Photoshop. During the week I work at Artist's for Humanity in the Graphic Design Studio, which is a great non-profit organization that employs kids to make art. I will be adding a link to my portfolio shortly.

Step 1: Setting Up the File

Open up a new Flash ActionScript 3.0 document, go to the Properties window (if it's not open go to Window > Properties) and click edit. Change the FPS to 50, the width to 1200px and the height to 800px.

In the timeline window (Window > Timeline) create two more layers, so there are three in total, then name the three: actions, speed, car. Lock the actions layer.

Step 2: Importing the Car Images

In the source files you'll find these three files:

  • carLeft.png
  • carRight.png
  • carStraight.png

Select the car layer and go to File > Import > Import to Stage and import the carStraight image.

Step 3: Making the Car MovieClip

Select the image and press F8, or Modify > Convert to Symbol. Leave all the settings as their defaults (top-left justified and a movieclip) and name it carMC.

Give the movieclip an instance name of carMC in the Properties window.

Double-click the image, or Rightclick > Edit. Select the image of the car and give it the coordinates x:-100, y:-230.

These can be changed to your liking, but I thought that these seemed to work the best and made the car turns look the most realistic.

Create two more keyframes after the current one.

Select the second keyframe, delete the image of the car and go to File > Import > Import to Stage and import the carLeft image. Then position it at -100,-230.

Do the same thing for the third keyframe and import the carRight image. Position that at -100,-230 as well.

Go into the actions of each keyframe (select the keyframe and hit F9 or Rightclick > Actions) and type in:

 stop();

Now double-click anywhere where there is nothing, or click on Scene 1 in the top left, to go back to the main artboard.

Because the car is so large compared to the stage, select the carMC and change its width to 100px and height to 189px. This scales down all three images, but allows you to bring the size back up if you need to later.

Next, select the carMC and center it on the stage using the align window.

So far we've set the file up, made a movieclip with three frames, each with an image in it and a stop(); command.

Step 3: Adding the Speedometer

When controlling the car there'll be an indicator on the screen telling you how fast it is going.

Grab the text tool and in your Properties panel (Window > Properties) make sure it says Dynamic Text, not Static or Input Text. Click anywhere on the artboard, where you would want the speedometer to be placed (I chose bottom left) and click. This should make a text box that is about 100 px wide. If it doesn't, or if this isn't wide enough, you can adjust it to a bigger size. Go back to the Properties panel and give the dynamic text and instance name of "speedometer".

Step 4: Taking a Look at all the Code

First I'll give you all the code so you can look over it and then I'll go through it piece by piece explaining it.

var increment:Number = 0;	//amount the car moves each frame
var carRotation:Number = carMC.rotation;	//rotation of the car
var posNeg:Number = 1;
var acceleration:Number = .05;	//acceleration of the car, or the amount increment gets increased by.
var speed:Number = 0;	//the speed of the car that will be displayed on screen
var maxSpeed:Number = 50;

//keyboard capture code start
var keyLeftPressed:Boolean;
var keyRightPressed:Boolean;
var keyUpPressed:Boolean;
var spaceBarPressed:Boolean;

addEventListener(Event.ENTER_FRAME,onEnterFrameFunction);
stage.addEventListener(KeyboardEvent.KEY_DOWN,keyPressed);
stage.addEventListener(KeyboardEvent.KEY_UP,keyReleased);
//keyboard capture code end


function onEnterFrameFunction(event:Event) {
	//detecting speed
	speed = Math.round((increment)*5);
	speedometer.text = String(speed);
	
	if ((carMC.rotation < 180)&&(carMC.rotation >= 0)){
		carRotation = carMC.rotation;
		posNeg = 1;
	}
	if ((carMC.rotation < 0)&&(carMC.rotation > -180)){
		carRotation = -1 * carMC.rotation;
		posNeg = -1;
	}
	
	//if Right key pressed rotate the car clockwise and change image to carRight
	if (keyRightPressed) {
		carMC.rotation += .5*increment;
		carMC.gotoAndStop(3);
	}
	
	//if Left key pressed rotate the car counterclockwise and change image to carLeft
	if (keyLeftPressed) {
		carMC.rotation -= .5*increment;
		carMC.gotoAndStop(2);
	}
	
	//if neither Left or Right key pressed change image to carStraight
	if (!keyLeftPressed && !keyRightPressed) {
		carMC.gotoAndStop(1);
	}
	
	//When up key is pressed...
	if (keyUpPressed) {
		carMC.y -= ((90-carRotation)/90)*increment;
			
		if (((carMC.rotation > 90)&&(carMC.rotation < 180))||((carMC.rotation < -90)&&(carMC.rotation > -180))) {
				carMC.x += posNeg * (((((1-(carRotation/360))*360)-180)/90)*increment);
		}
		if (((carMC.rotation <= 90)&&(carMC.rotation > 0))||((carMC.rotation >= -90)&&(carMC.rotation < -1))) {			
				carMC.x += posNeg * ((carRotation)/90)*increment;
		}
		if (spaceBarPressed) {
			increment -= .5*acceleration;
		}
		if (!spaceBarPressed && speed < maxSpeed) {
			increment += acceleration;
		}
	}
   
	else {
		if (increment > 0 && spaceBarPressed) {
			carMC.y -= ((90-carRotation)/90)*increment;
			
			if (((carMC.rotation > 90)&&(carMC.rotation < 180))||((carMC.rotation < -90)&&(carMC.rotation > -180))) {
				carMC.x += posNeg * (((((1-(carRotation/360))*360)-180)/90)*increment);
			}
			if (((carMC.rotation <= 90)&&(carMC.rotation > 0))||((carMC.rotation >= -90)&&(carMC.rotation < -1))) {
				carMC.x += posNeg * ((carRotation)/90)*increment;
			}
			increment -= 4*acceleration;
		}
		else if (increment > 0) {
			carMC.y -= ((90-carRotation)/90)*increment;
			
			if (((carMC.rotation > 90)&&(carMC.rotation < 180))||((carMC.rotation < -90)&&(carMC.rotation > -180))) {
				carMC.x += posNeg * (((((1-(carRotation/360))*360)-180)/90)*increment);
			}
			if (((carMC.rotation <= 90)&&(carMC.rotation > 0))||((carMC.rotation >= -90)&&(carMC.rotation < -1))) {
				carMC.x += posNeg * ((carRotation)/90)*increment;
			}
			increment -= 1.5*acceleration;
		}
		else
			increment = 0;
	}
}

function keyPressed(event:KeyboardEvent) {
	if (event.keyCode == Keyboard.LEFT)
		keyLeftPressed = true;
	if (event.keyCode == Keyboard.RIGHT)
		keyRightPressed = true;
	if (event.keyCode == Keyboard.UP)
		keyUpPressed = true;
	if (event.keyCode == Keyboard.SPACE)
		spaceBarPressed = true;
}

function keyReleased(event:KeyboardEvent) {
	if (event.keyCode == Keyboard.LEFT)
		keyLeftPressed = false;
	if (event.keyCode == Keyboard.RIGHT)
		keyRightPressed = false;
	if (event.keyCode == Keyboard.UP)
		keyUpPressed = false;
	if (event.keyCode == Keyboard.SPACE)
		spaceBarPressed = false;
}

Step 5: Adding Variables

Click on the first frame of the actions layer that you locked earlier and press F9 (or Right click > Actions). Add the code in here.

These are the variables we will need.

var increment:Number = 0;	//amount the car moves each frame
var carRotation:Number = carMC.rotation;	//rotation of the car
var posNeg:Number = 1;
var acceleration:Number = .05;	//acceleration of the car, or the amount increment gets increased by.
var speed:Number = 0;	//the speed of the car that will be displayed on screen
var maxSpeed:Number = 50;	//The max speed the car can travel

Step 6: Listening for Keypresses

The explanations are all here, except posNeg which I'll explain later.

var keyLeftPressed:Boolean;
var keyRightPressed:Boolean;
var keyUpPressed:Boolean;
var spaceBarPressed:Boolean;

addEventListener(Event.ENTER_FRAME,onEnterFrameFunction);
stage.addEventListener(KeyboardEvent.KEY_DOWN,keyPressed);
stage.addEventListener(KeyboardEvent.KEY_UP,keyReleased);

When moving over to AS3 this was one of the more confusing parts for me. In AS2 creating functions to be called was much easier to code. You would usually just have an "if" statement inside an onEnterFrame function that looked to see if _____ key was down. In AS3 there is a way to do this similarly, but it doesn't work well with games. The movements aren't smooth and you cannot press two keys at a time.

I did it here with booleans. For my game I'm only looking to see if four keys are pressed: Up, Left, Right, and Space, so I created a boolean for each of them. I then added three listeners.

 addEventListener(Event.ENTER_FRAME,onEnterFrameFunction);\

This code is pretty much equivalent to onEnterFrame. On every frame (so in our case 50 times a second) it performs the function onEnterFrameFunction. The reason being because it will allow us to continually update variables, like speed, whilst also checking if a key has been pressed (which it does indirectly through a boolean, as you'll see in a second).

stage.addEventListener(KeyboardEvent.KEY_DOWN,keyPressed);
stage.addEventListener(KeyboardEvent.KEY_UP,keyReleased);

These are two listeners that are added to the stage. What they do is when a key (any key) is pressed, the function keyPressed gets called. When a key is released, the function keyReleased is called.

function keyPressed(event:KeyboardEvent) {
	if (event.keyCode == Keyboard.LEFT)
		keyLeftPressed = true;
	if (event.keyCode == Keyboard.RIGHT)
		keyRightPressed = true;
	if (event.keyCode == Keyboard.UP)
		keyUpPressed = true;
	if (event.keyCode == Keyboard.SPACE)
		spaceBarPressed = true;
}

function keyReleased(event:KeyboardEvent) {
	if (event.keyCode == Keyboard.LEFT)
		keyLeftPressed = false;
	if (event.keyCode == Keyboard.RIGHT)
		keyRightPressed = false;
	if (event.keyCode == Keyboard.UP)
		keyUpPressed = false;
	if (event.keyCode == Keyboard.SPACE)
		spaceBarPressed = false;
}

This code comes at the end of my code, but I am explaining it now because it concerns key presses.

These are the two functions keyPressed and keyReleased. Like I said above, when a key is pressed keyPressed gets called. It checks the four "if" statements to see if the key pressed is any of the four keys my program is looking for. If the key is one of them, it sets the boolean of that key to true.

What keyReleased does is the opposite. When a key is released it checks to see if it is one of the four keys. Should this be the case, it will set the boolean of that key back to false.

Step 7: Understanding How Moving the Car Works

If we were coding a game where hitting the left key moved the car in the -x direction, and hitting the up key moved the car in the +y direction, things would be much simpler. This program is different. As there is no built in function in Flash which will move the car forward based on its current direction, we must create it ourselves. While making this code I had to do a lot of trial and error and I found that working backwards helped the most. I knew that when the card was facing N, or 0 degrees, it should move in the +x direction at full speed. Then should it be facing NE, or 45 degrees, it would move in the +x direction at half speed, and in the +y direction at half speed.

Step 8: Adding onEnterFrame Function

First we'll add the onEnterFrame function. Like I said above, this function will be called on every frame.

function onEnterFrameFunction(event:Event) {

}

Step 9: Coding the Keys

Now we'll add functions which are called when a key is pressed.

Remember that when any key is pressed the keyPressed function is called. If it's one of the four keys the program is looking for, it will set that key's boolean to true and when that key is released the boolean will be set to false. Whenever a key is being held down, its boolean will be true.

function onEnterFrameFunction(event:Event) {
	if (keyRightPressed) {

	}
	
	if (keyLeftPressed) {

	}
	
	if (!keyLeftPressed && !keyRightPressed) {

	}
	
	if (keyUpPressed) {

	}
   
	else {

	}
}

Step 10: Rotating the Car

function onEnterFrameFunction(event:Event) {
	if (keyRightPressed) {
		carMC.rotation += .5*increment;
	}
	
	if (keyLeftPressed) {
		carMC.rotation -= .5*increment;
	}
	
	if (!keyLeftPressed && !keyRightPressed) {

	}
	
	if (keyUpPressed) {

	}
   
	else {

	}
}

Step 11: Making the Car Wheels Turn

When the car turns we want it to look realistic, so we'll use the other images (carLeft and carRight) to make the wheels appear to be turning.

function onEnterFrameFunction(event:Event) {
	if (keyRightPressed) {
		carMC.rotation += .5*increment;
		carMC.gotoAndStop(3);
	}
	
	if (keyLeftPressed) {
		carMC.rotation -= .5*increment;
		carMC.gotoAndStop(2);
	}
	
	if (!keyLeftPressed && !keyRightPressed) {
		carMC.gotoAndStop(1);
	}
	
	if (keyUpPressed) {

	}
   
	else {

	}
}

When the left key is pressed carLeft will appear, when the right key is pressed carRight will appear. When neither are being pressed carStraight will appear.

Step 12: Getting the Car's Rotation

I'll not go too deep into the explanation of the math, because it's either something you get or you don't. However, I'll try to explain it as best I can. Like I said, a lot of this was trial and error and working backwards, which I'll explain as I go along.

The way flash stores the rotation of an object is not from 0>360, it's from -180>180, where -180 = 180.

function onEnterFrameFunction(event:Event) {
	if ((carMC.rotation < 180)&&(carMC.rotation >= 0)){
		carRotation = carMC.rotation;
		posNeg = 1;
	}
	if ((carMC.rotation < 0)&&(carMC.rotation > -180)){
		carRotation = -1 * carMC.rotation;
		posNeg = -1;
	}

	if (keyRightPressed) {
		carMC.rotation += .5*increment;
		carMC.gotoAndStop(3);
	}
	
	if (keyLeftPressed) {
		carMC.rotation -= .5*increment;
		carMC.gotoAndStop(2);
	}
	
	if (!keyLeftPressed && !keyRightPressed) {
		carMC.gotoAndStop(1);
	}
	
	if (keyUpPressed) {

	}
   
	else {

	}
}

What this code does is takes the rotation of the car and gets the absolute value of it, so it will always be positive. Then it stores either 1 (if it was originally positive) or -1 (if it was originally negative) into the variable posNeg, which we will use later.

Step 13: Coding the Up Button

This is where all the majic happens.

In order to save room and make it easier to understand I won't paste the other code that was previously added before this step. All code in this step is added in between here:

if (keyUpPressed) {

}

Step 14: Moving the Car in the Y Direction

Instead of going through and explaining it, here is a table describing how the car should move in the y direction based on its rotation.

Degrees (°) Amount to move in Y
-180 -1
-135 -.5
-90 0
-45 .5
0 1
45 .5
90 0
135 -.5
180 -1

When the car is between -90 and 90 it is facing N to some degree and when it is between -180 and -90, or 90 and 180 it is facing S to some degree.

With some quick math I came up with this equation:

carMC.y -= ((90-carRotation)/90)*increment;

Step 15: Moving the Car in the X Direction

Determining how much the car should move in the x direction takes a bit more work.

Degrees (°) Amount to move in X
-180 0
-135 -.5
-90 1
-45 .5
0 0
45 .5
90 1
135 -.5
180 0
		if (((carMC.rotation > 90)&&(carMC.rotation < 180))||((carMC.rotation < -90)&&(carMC.rotation > -180))) {
				carMC.x += posNeg * (((((1-(carRotation/360))*360)-180)/90)*increment);
		}
		if (((carMC.rotation <= 90)&&(carMC.rotation > 0))||((carMC.rotation >= -90)&&(carMC.rotation < 0))) {			
				carMC.x += posNeg * ((carRotation)/90)*increment;
		}

The first "if" deals with the car facing S and the second when it is facing N.

Step 16: Putting the Code Together

That is the basis of calculating the movement and this is what you should have so far in the onEnterFrame function:

function onEnterFrameFunction(event:Event) {
	if ((carMC.rotation < 180)&&(carMC.rotation >= 0)){
		carRotation = carMC.rotation;
		posNeg = 1;
	}
	if ((carMC.rotation < 0)&&(carMC.rotation > -180)){
		carRotation = -1 * carMC.rotation;
		posNeg = -1;
	}

	if (keyRightPressed) {
		carMC.rotation += .5*increment;
		carMC.gotoAndStop(3);
	}
	
	if (keyLeftPressed) {
		carMC.rotation -= .5*increment;
		carMC.gotoAndStop(2);
	}
	
	if (!keyLeftPressed && !keyRightPressed) {
		carMC.gotoAndStop(1);
	}
	
	if (keyUpPressed) {
		carMC.y -= ((90-carRotation)/90)*increment;
			
		if (((carMC.rotation > 90)&&(carMC.rotation < 180))||((carMC.rotation < -90)&&(carMC.rotation > -180))) {
				carMC.x += posNeg * (((((1-(carRotation/360))*360)-180)/90)*increment);
		}
		if (((carMC.rotation <= 90)&&(carMC.rotation > 0))||((carMC.rotation >= -90)&&(carMC.rotation < 0))) {			
				carMC.x += posNeg * ((carRotation)/90)*increment;
		}
	}
   
	else {

	}
}

Step 17: Adding Acceleration

If you were to run the program right now (which you probably can't since the code isn't complete) our car would not react to the up key being pressed. This is because increment=0. So we must add a line of code that increases this, but will stop increasing it once our car reaches top speed.

function onEnterFrameFunction(event:Event) {
	if ((carMC.rotation < 180)&&(carMC.rotation >= 0)){
		carRotation = carMC.rotation;
		posNeg = 1;
	}
	if ((carMC.rotation < 0)&&(carMC.rotation > -180)){
		carRotation = -1 * carMC.rotation;
		posNeg = -1;
	}

	if (keyRightPressed) {
		carMC.rotation += .5*increment;
		carMC.gotoAndStop(3);
	}
	
	if (keyLeftPressed) {
		carMC.rotation -= .5*increment;
		carMC.gotoAndStop(2);
	}
	
	if (!keyLeftPressed && !keyRightPressed) {
		carMC.gotoAndStop(1);
	}
	
	if (keyUpPressed) {
		carMC.y -= ((90-carRotation)/90)*increment;
			
		if (((carMC.rotation > 90)&&(carMC.rotation < 180))||((carMC.rotation < -90)&&(carMC.rotation > -180))) {
				carMC.x += posNeg * (((((1-(carRotation/360))*360)-180)/90)*increment);
		}
		if (((carMC.rotation <= 90)&&(carMC.rotation > 0))||((carMC.rotation >= -90)&&(carMC.rotation < 0))) {			
				carMC.x += posNeg * ((carRotation)/90)*increment;
		}
		if (speed < maxSpeed) {
			increment += acceleration;
		}
	}
   
	else {

	}
}

Step 18: Releasing the Gas

When you release the gas pedal on a car it begins to slowly decellerate due to many factors: Wind, drag, friction... so we must make the car slow down when the up arrow is not being pressed.

function onEnterFrameFunction(event:Event) {
	if ((carMC.rotation < 180)&&(carMC.rotation >= 0)){
		carRotation = carMC.rotation;
		posNeg = 1;
	}
	if ((carMC.rotation < 0)&&(carMC.rotation > -180)){
		carRotation = -1 * carMC.rotation;
		posNeg = -1;
	}

	if (keyRightPressed) {
		carMC.rotation += .5*increment;
		carMC.gotoAndStop(3);
	}
	
	if (keyLeftPressed) {
		carMC.rotation -= .5*increment;
		carMC.gotoAndStop(2);
	}
	
	if (!keyLeftPressed && !keyRightPressed) {
		carMC.gotoAndStop(1);
	}
	
	if (keyUpPressed) {
		carMC.y -= ((90-carRotation)/90)*increment;
			
		if (((carMC.rotation > 90)&&(carMC.rotation < 180))||((carMC.rotation < -90)&&(carMC.rotation > -180))) {
				carMC.x += posNeg * (((((1-(carRotation/360))*360)-180)/90)*increment);
		}
		if (((carMC.rotation <= 90)&&(carMC.rotation > 0))||((carMC.rotation >= -90)&&(carMC.rotation < 0))) {			
				carMC.x += posNeg * ((carRotation)/90)*increment;
		}
		if (speed < maxSpeed) {
			increment += acceleration;
		}
	}
   
	else {
		if (increment > 0) {
			carMC.y -= ((90-carRotation)/90)*increment;
			if (((carMC.rotation > 90)&&(carMC.rotation < 180))||((carMC.rotation < -90)&&(carMC.rotation > -180))) {
				carMC.x += posNeg * (((((1-(carRotation/360))*360)-180)/90)*increment);
			}
			if (((carMC.rotation <= 90)&&(carMC.rotation > 0))||((carMC.rotation >= -90)&&(carMC.rotation < -1))) {
				carMC.x += posNeg * ((carRotation)/90)*increment;
			}
			increment -= 1.5*acceleration;
		}
		else
			increment = 0;
	}
}

What the code does is if the Up key is not being pressed and increment is above 0, it starts to lower the increment. If the increment is not above 0 make it 0, or else the car will move backwards.

Notice that the code inside the "if" statement is the same code we added inside if (keyUpPressed) except that increment is now being lowered.

Step 20: Applying the Brake

Since the car cannot just rely on drag to stop it, we must also add a brake, which will be coded to the spacebar.

The code for this will have to be placed in multiple places.

	if (keyUpPressed) {
		carMC.y -= ((90-carRotation)/90)*increment;
			
		if (((carMC.rotation > 90)&&(carMC.rotation < 180))||((carMC.rotation < -90)&&(carMC.rotation > -180))) {
				carMC.x += posNeg * (((((1-(carRotation/360))*360)-180)/90)*increment);
		}
		if (((carMC.rotation <= 90)&&(carMC.rotation > 0))||((carMC.rotation >= -90)&&(carMC.rotation < 0))) {			
				carMC.x += posNeg * ((carRotation)/90)*increment;
		}
		if (spaceBarPressed) {
			increment -= .5*acceleration;
		}
		if (!spaceBarPressed && speed < maxSpeed) {
			increment += acceleration;
		}
	}

This code states that if the spacebar is pressed while the up arrow key is pressed, decellerate, but at a slower pace. I then added code to an "if" statement we made earlier to make sure it was not executed if the spacebar was pressed.

We also need to add code when the up key is not being pressed and the spacebar is.

	if (keyUpPressed) {
		carMC.y -= ((90-carRotation)/90)*increment;
			
		if (((carMC.rotation > 90)&&(carMC.rotation < 180))||((carMC.rotation < -90)&&(carMC.rotation > -180))) {
				carMC.x += posNeg * (((((1-(carRotation/360))*360)-180)/90)*increment);
		}
		if (((carMC.rotation <= 90)&&(carMC.rotation > 0))||((carMC.rotation >= -90)&&(carMC.rotation < 0))) {			
				carMC.x += posNeg * ((carRotation)/90)*increment;
		}
		if (spaceBarPressed) {
			increment -= .5*acceleration;
		}
		if (!spaceBarPressed && speed < maxSpeed) {
			increment += acceleration;
		}
	}
   
	else {
		if (increment > 0 && spaceBarPressed) {
			carMC.y -= ((90-carRotation)/90)*increment;
			
			if (((carMC.rotation > 90)&&(carMC.rotation < 180))||((carMC.rotation < -90)&&(carMC.rotation > -180))) {
				carMC.x += posNeg * (((((1-(carRotation/360))*360)-180)/90)*increment);
			}
			if (((carMC.rotation <= 90)&&(carMC.rotation > 0))||((carMC.rotation >= -90)&&(carMC.rotation < -1))) {
				carMC.x += posNeg * ((carRotation)/90)*increment;
			}
			increment -= 4*acceleration;
		}
		else if (increment > 0) {
			carMC.y -= ((90-carRotation)/90)*increment;
			
			if (((carMC.rotation > 90)&&(carMC.rotation < 180))||((carMC.rotation < -90)&&(carMC.rotation > -180))) {
				carMC.x += posNeg * (((((1-(carRotation/360))*360)-180)/90)*increment);
			}
			if (((carMC.rotation <= 90)&&(carMC.rotation > 0))||((carMC.rotation >= -90)&&(carMC.rotation < -1))) {
				carMC.x += posNeg * ((carRotation)/90)*increment;
			}
			increment -= 1.5*acceleration;
		}
		else
			increment = 0;
	}

Step 21: Adding Speedometer Code

Last but not least we have to add the code which detects the speed and sends it to the speedometer.

Just after:

function onEnterFrameFunction(event:Event) {

Add:

speed = Math.round((increment)*5);
speedometer.text = String(speed);

Step 22: Finalizing

That pretty much sums this tutorial up. What this program can do is pretty basic and I just wanted to outline the major parts in making a game like this. After grasping the concepts in this tutorial you can also code in the down key, make boundaries for the car, even make a racing game. I hope that you learned at least a little bit from this tutorial and thanks for reading it.

Final Code:

var increment:Number = 0;	//amount the car moves each frame
var carRotation:Number = carMC.rotation;	//rotation of the car
var posNeg:Number = 1;
var acceleration:Number = .05;	//acceleration of the car, or the amount increment gets increased by.
var speed:Number = 0;	//the speed of the car that will be displayed on screen
var maxSpeed:Number = 50;	//The max speed the car can travel

//keyboard capture code start
var keyLeftPressed:Boolean;
var keyRightPressed:Boolean;
var keyUpPressed:Boolean;
var spaceBarPressed:Boolean;

addEventListener(Event.ENTER_FRAME,onEnterFrameFunction);
stage.addEventListener(KeyboardEvent.KEY_DOWN,keyPressed);
stage.addEventListener(KeyboardEvent.KEY_UP,keyReleased);
//keyboard capture code end


function onEnterFrameFunction(event:Event) {
	//detecting speed
	speed = Math.round((increment)*5);
	speedometer.text = String(speed);
	
	if ((carMC.rotation < 180)&&(carMC.rotation >= 0)){
		carRotation = carMC.rotation;
		posNeg = 1;
	}
	if ((carMC.rotation < 0)&&(carMC.rotation > -180)){
		carRotation = -1 * carMC.rotation;
		posNeg = -1;
	}
	
	//if Right key pressed rotate the car clockwise and change image to carRight
	if (keyRightPressed) {
		carMC.rotation += .5*increment;
		carMC.gotoAndStop(3);
	}
	
	//if Left key pressed rotate the car counterclockwise and change image to carLeft
	if (keyLeftPressed) {
		carMC.rotation -= .5*increment;
		carMC.gotoAndStop(2);
	}
	
	//if neither Left or Right key pressed change image to carStraight
	if (!keyLeftPressed && !keyRightPressed) {
		carMC.gotoAndStop(1);
	}
	
	//When up key is pressed...
	if (keyUpPressed) {
		carMC.y -= ((90-carRotation)/90)*increment;
			
		if (((carMC.rotation > 90)&&(carMC.rotation < 180))||((carMC.rotation < -90)&&(carMC.rotation > -180))) {
				carMC.x += posNeg * (((((1-(carRotation/360))*360)-180)/90)*increment);
		}
		if (((carMC.rotation <= 90)&&(carMC.rotation > 0))||((carMC.rotation >= -90)&&(carMC.rotation < -1))) {			
				carMC.x += posNeg * ((carRotation)/90)*increment;
		}
		if (spaceBarPressed) {
			increment -= .5*acceleration;
		}
		if (!spaceBarPressed && speed < maxSpeed) {
			increment += acceleration;
		}
	}
   
	else {
		if (increment > 0 && spaceBarPressed) {
			carMC.y -= ((90-carRotation)/90)*increment;
			
			if (((carMC.rotation > 90)&&(carMC.rotation < 180))||((carMC.rotation < -90)&&(carMC.rotation > -180))) {
				carMC.x += posNeg * (((((1-(carRotation/360))*360)-180)/90)*increment);
			}
			if (((carMC.rotation <= 90)&&(carMC.rotation > 0))||((carMC.rotation >= -90)&&(carMC.rotation < -1))) {
				carMC.x += posNeg * ((carRotation)/90)*increment;
			}
			increment -= 4*acceleration;
		}
		else if (increment > 0) {
			carMC.y -= ((90-carRotation)/90)*increment;
			
			if (((carMC.rotation > 90)&&(carMC.rotation < 180))||((carMC.rotation < -90)&&(carMC.rotation > -180))) {
				carMC.x += posNeg * (((((1-(carRotation/360))*360)-180)/90)*increment);
			}
			if (((carMC.rotation <= 90)&&(carMC.rotation > 0))||((carMC.rotation >= -90)&&(carMC.rotation < -1))) {
				carMC.x += posNeg * ((carRotation)/90)*increment;
			}
			increment -= 1.5*acceleration;
		}
		else
			increment = 0;
	}
}

function keyPressed(event:KeyboardEvent) {
	if (event.keyCode == Keyboard.LEFT)
		keyLeftPressed = true;
	if (event.keyCode == Keyboard.RIGHT)
		keyRightPressed = true;
	if (event.keyCode == Keyboard.UP)
		keyUpPressed = true;
	if (event.keyCode == Keyboard.SPACE)
		spaceBarPressed = true;
}

function keyReleased(event:KeyboardEvent) {
	if (event.keyCode == Keyboard.LEFT)
		keyLeftPressed = false;
	if (event.keyCode == Keyboard.RIGHT)
		keyRightPressed = false;
	if (event.keyCode == Keyboard.UP)
		keyUpPressed = false;
	if (event.keyCode == Keyboard.SPACE)
		spaceBarPressed = false;
}

Enjoy this Post?

We'd love your vote!

User Comments

( ADD YOURS )
  1. PG

    Stephen Cronin July 10th

    Hope you guys like the tutorial. If you have any suggestions about what I should/shouldn’t do please let me know. If people like this tutorial enough I will make a second one focusing on adding boundaries and realistic collisions.

    ( Reply )
    1. PG

      Toni July 29th

      Can you make tutorial for adding boundaries?

      ( Reply )
  2. PG

    james July 10th

    wow so much damn code to make such a simple product

    ( Reply )
  3. PG

    Stephen Cronin July 10th

    Also, sorry for some of my bad grammar and spelling mistakes, I guess I looked over those when I was trying to make sure I pasted in the code correctly.

    ( Reply )
  4. PG

    Benjamin Reid July 10th

    Urm… I just drove the car off the screen in the demo. Now I can’t get it back!

    :(

    There should be a restriction at the boundary. All games should have limits.

    ( Reply )
    1. PG

      Stephen Cronin July 10th

      Yeah, I was planning on implementing that along with a few other things in another tutorial if there was enough interest in this one.

      ( Reply )
  5. PG

    André July 10th

    WOWW, how much lines man, you should learn the Math class before creating this tutorial.

    See an example i´ve done some months ago:
    http://cavallari.freehostia.com/cardrive/

    And it´s source code is here:
    http://www.4shared.com/file/117167004/143550e6/cardrive.html

    Much less lines and the movement is very smooth, and this example the car goes backward too.

    ( Reply )
    1. PG

      Danke Willis July 10th

      Sorry but obviously you don’t know a thing about what you’re talking about. Maybe you should stick to flash animations!

      ( Reply )
      1. PG

        André July 10th

        Sorry, but it seems that YOU dont know anything about what´s been talked about here and just want to cause a discussion.

    2. PG

      Erick July 10th

      Yea One uses the Math Class. The Lines of code would be so much less. I would say under a 70 or 50 Lines

      ( Reply )
    3. PG

      David July 10th

      I read your source files, great solution and few lines. Thanks a lot man, and very very easy, but i still dont know how to work with Math class, but it seems to be easy, if not asking so much, please make a tutorial on Math class for gaming develop.

      Stephen, thanks fo sharing too, but the other solution is more simple and easyer.

      ( Reply )
    4. PG

      Stephen Cronin July 10th

      I downloaded the source code zip, but there are only the swfs so I cannot see the code. Would like to check it out though.

      ( Reply )
    5. PG

      André July 10th

      Correcting the source codes:
      http://www.4shared.com/file/117289092/f5eff566/Cardrive.html

      Now it´s ok…

      ( Reply )
      1. PG

        Erick July 10th

        The Math Class is very simple. As long as you know some math. :)

      2. PG

        kmad July 29th

        Indeed, just to elaborate on what Erick said, essentially it isn’t the Math class that it is important to learn but the math itself. In this case, trigonometry. The Math class itself just gives you access to certain functions, in particular, trigonometric functions such as sine, cosine and tangent.

  6. PG

    Alex July 10th

    I was hoping you’d have implemented this with some OOP.

    Trying to use anything like this in a production environment is asking to have your evenings and weekends taken from you so you can be at work 24/7 fixing the code. I can just imagine the pain one would have to go through to add some basic game logic to all that.

    ( Reply )
  7. PG

    Dario Gutierrez July 10th

    Great begin for develop a mini game. Thanks dude.

    ( Reply )
  8. PG

    HrMoller July 10th

    I think it’s a great tutorial! more of that please – anyways som more OOP orientation would be even more great.

    The has a speedlimit of 50 when it goes forward but when you reverse it, it seems ike there’s no limit…?

    ( Reply )
    1. PG

      Stephen Cronin July 10th

      I didn’t code the program to make the car go backwards.

      ( Reply )
  9. PG

    Jônatan Fróes July 10th

    Thanks a lot!

    ( Reply )
  10. PG

    Midnyt July 10th

    Another thing to think about… You put a limit on the forward speed of the car, but driving in reverse, there is no speed limiter. Try it out.

    ( Reply )
  11. PG

    Eli McMakin July 10th

    I would think that the fact that he is using AS 2.0 would make it difficult to use OOP. AS 3.0 is a much more advanced coding language.

    Can anyone confirm?

    ( Reply )
    1. PG

      Stephen Cronin July 10th

      Yeah, like I said in the tut I have just started using as3. I wanted to make the tutorial easy for as2 users to understand and not go too in depth with oop.

      ( Reply )
    2. PG

      André July 12th

      He is using AS 3.0 document, see the first line of the step 1.

      But, the Math class exists both in AS2.0 and AS3.0, he would create a better tutorial if he used the Math class.

      My opinion:
      He said he wanted to make the tutorial ease for AS2 and dont go in depth with OOP, so he should have used the AS2 document not AS3, AS3 users would know to convert it to AS3, but AS2 maybe not, and the AS3 is 100% OOP, and any try to get out from this will teach bad habits for AS3, for example the use of timeline to code, when the correct for AS3 is the document class. Just things to think about before creating a tutorial. ActionScript 2.0 is one thing and ActionScript 3.0 is another thing very different.

      ( Reply )
    3. PG

      Alex July 13th

      OOP was still easy in AS2. They just added a few more things in AS3 to make it easier.

      The only noticable difference for the average user is the document class.

      ( Reply )
      1. PG

        André July 13th

        AS3 isnt easyer, and it´s very different of AS2, the best difference is the document class and the classes for objects, another big difference is that now AS3 is 100% OOP, and the AS2 isnt.

  12. PG

    RUGRLN July 11th

    Nice but, some boundaries would be good so you don’t drive off the scene and can never find your way back!! Or so we could make it into a mini racing game!!

    ( Reply )
  13. PG

    aldisrolf July 15th

    Good to see the application but the code is huge for such a small application. I also prepare codes for some of the Driving games. I love to execute them in different manners.

    ( Reply )
  14. PG

    Javier July 15th

    It seems pretty ok for me, even the code. Remember this is for begginers. Of course you could change things with math, but it wouldn’t be as readable as it is.

    ( Reply )
    1. PG

      André July 16th

      If you get some tutorial to read abou Math class and try to create this tutorial using the Math class, you will take less time =)

      ( Reply )
  15. PG

    nemo July 17th

    You read or not, I in a shock, your work has inspired me thanks. (Wrote through the translator)

    ( Reply )
  16. PG

    Jordan July 22nd

    Very Good, Possibly add Background and Boundries. Would be perfect with a reverse :)

    ( Reply )
  17. PG

    ajay July 26th

    hi i cant get the game i didnot get the source can u help me pls
    can u explain how to get the direction man

    ( Reply )
  18. PG

    matthew July 28th

    hey do u knw were i can find a good link to make a animated website?

    ( Reply )
  19. PG

    Fusion August 9th

    Why not make a “micro machines” style game tutorial?

    ( Reply )
  20. PG

    Lisa September 10th

    Thanks for taking the time to do this. It’s very helpful to use beginners to understand the concepts behind some of this stuff. Sure, then we can go on to learning about the math thing and all that, but sometimes having it broken down like this is helpful in just GETTING IT first. After we GET IT, then we can move on to learning shortcuts. Much appreciated.

    Yeah, would love some info on boundaries! Thanks.

    ( Reply )
  21. PG

    manoj sahi October 3rd

    BUG ::

    Press SPACE BAR + UP_KEY

    car accelerates in backward direction.

    ( Reply )
  1. Arrow
    Gravatar

    Your Name
    October 3rd