Free ActionScript

Flash AS2 & AS3 Tutorials, Game Code, Effects, Source Files & Sample Downloads

Car Movement: Acceleration, Turning & Braking

AS3 version of my previous GTA style top-down view car driving game example. This example shows you how to implement car movement; Acceleration, Braking & Turning.

View Code ACTIONSCRIPT
/**
 * Car Movement - Accelerate, Brake, Rotate & Reverse
 * ---------------------
 * VERSION: 2.0
 * DATE: 1/09/2011
 * AS3
 * UPDATES AND DOCUMENTATION AT: http://www.FreeActionScript.com
 **/
package com.freeactionscript
{
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.ui.Keyboard;
 
	public class Car extends Sprite
	{
		//Settings
		private var speed:Number = 0;
		private var speedMax:Number = 8;
		private var speedMaxReverse:Number = -3;
		private var speedAcceleration:Number = .15;
		private var speedDeceleration:Number = .90;
		private var groundFriction:Number = .95;
 
		private var steering:Number = 0;
		private var steeringMax:Number = 2;
		private var steeringAcceleration:Number = .10;
		private var steeringFriction:Number = .98;
 
		private var velocityX:Number = 0;
		private var velocityY:Number = 0;
 
		private var up:Boolean = false;
		private var down:Boolean = false;
		private var left:Boolean = false;
		private var right:Boolean = false;
 
		public function Car()
		{
			addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
		}
 
		private function onAddedToStage(event:Event):void
		{
			removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
 
			init();
		}
 
		private function init():void
		{
			stage.addEventListener(Event.ENTER_FRAME, runGame);
			stage.addEventListener(KeyboardEvent.KEY_DOWN, myOnPress);
			stage.addEventListener(KeyboardEvent.KEY_UP, myOnRelease);
		}
 
		private function runGame(event:Event):void
		{
			if (up)
			{
				//check if below speedMax
				if (speed < speedMax) 				{ 					//speed up 					speed += speedAcceleration; 					//check if above speedMax 					if (speed > speedMax)
					{
						//reset to speedMax
						speed = speedMax;
					}
				}
			}
 
			if (down)
			{
				//check if below speedMaxReverse
				if (speed > speedMaxReverse)
				{
					//speed up (in reverse)
					speed -= speedAcceleration;
					//check if above speedMaxReverse
					if (speed < speedMaxReverse) 					{ 						//reset to speedMaxReverse 						speed = speedMaxReverse; 					} 				} 			} 			 			if (left) 			{ 				//turn left 				steering -= steeringAcceleration; 				//check if above steeringMax 				if (steering > steeringMax)
				{
					//reset to steeringMax
					steering = steeringMax;
				}
			}
 
			if (right)
			{
				//turn right
				steering += steeringAcceleration;
				//check if above steeringMax
				if (steering < -steeringMax) 				{ 					//reset to steeringMax 					steering = -steeringMax; 				} 			} 			 			// friction     			speed *= groundFriction; 			 			// prevent drift 			if(speed > 0 && speed < 0.05) 			{ 				speed = 0 			} 			 			// calculate velocity based on speed 			velocityX = Math.sin (this.rotation * Math.PI / 180) * speed; 			velocityY = Math.cos (this.rotation * Math.PI / 180) * -speed; 			 			// update position	 			this.x += velocityX; 			this.y += velocityY; 			 			// prevent steering drift (right) 			if(steering > 0)
			{
				// check if steering value is really low, set to 0
				if(steering < 0.05)
				{
					steering = 0;
				}
			}
			// prevent steering drift (left)
			else if(steering < 0) 			{ 				// check if steering value is really low, set to 0 				if(steering > -0.05)
				{
					steering = 0;
				}
			}
 
			// apply steering friction
			steering = steering * steeringFriction;
 
			// make car go straight after driver stops turning
			steering -= (steering * 0.1);
 
			// rotate
			this.rotation += steering * speed;
		}
 
		/**
		 * Keyboard Handlers
		 */
		private function myOnPress(event:KeyboardEvent):void
		{
			switch( event.keyCode )
			{
				case Keyboard.UP:
					up = true;
					break;
 
				case Keyboard.DOWN:
					down = true;
					break;
 
				case Keyboard.LEFT:
					left = true;
					break;
 
				case Keyboard.RIGHT:
					right = true;
					break;
			}
 
			event.updateAfterEvent();
		}
 
		private function myOnRelease(event:KeyboardEvent):void
		{
			switch( event.keyCode )
			{
				case Keyboard.UP:
					up = false;
					break;
 
				case Keyboard.DOWN:
					down = false;
					break;
 
				case Keyboard.LEFT:
					left = false;
					break;
 
				case Keyboard.RIGHT:
					right = false;
					break;
			}
 
		}
 
	}
 
}
Download Fla Sample

Download Fla Sample

Wishlist
-Car leaves tire marks

Updates
Version 2.0 – 01/09/2011
-Re-wrote most of the code
-Fixed drifting bug
-Fixed reverse
-Added car starting rotation (just set car’s rotation property)

Endless Starfield – Parallax Scrolling

AS3 version of my endless starfield & parallax scrolling effect. This is a huge improvement over the last script in terms of performance and ease-of-use.

This version lets you set the width, height, and speed of the starfield, as well as position it anywhere on stage by setting the X & Y coordinates (old version only allowed it to be fullscreen).

This is great because you’ll now be able to use it in games (top-down and side scrollers), any size banners (horizontal or skyscrapers), and anywhere else you need the effect.

Using it is pretty simple:
parallaxField.createField(containerMC, x, y, width, height, numberOfStars, speedX, speedY);

You can also use:
parallaxField.enable();
parallaxField.disable();
To start and stop the effect.

See Main.as for exact usage examples.

View Code ACTIONSCRIPT
/**
 * Endless Starfield - Parallax Scrolling
 * ---------------------
 * VERSION: 1.0
 * DATE: 6/26/2010
 * AS3
 * UPDATES AND DOCUMENTATION AT: http://www.FreeActionScript.com
 **/
package com.freeactionscript
{
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.utils.getDefinitionByName;
 
	public class ParallaxField extends MovieClip
	{
		// settings & vars
		private var acceleration:Number = .25;
 
		private var starBox:Sprite;		
		private var starsArray:Array = [];
		private var starArrayLength:int;
 
		private static var STAR_SMALL:String = "small";
		private static var STAR_NORMAL:String = "normal";
		private static var STAR_LARGE:String = "large";	
 
		private var pathToContainer:MovieClip;
 
		private var containerX:int;
		private var containerY:int;
 
		private var containerWidth:int;
		private var containerHeight:int;
 
		private var speedX:Number;
		private var speedY:Number;
 
		private var isStarted:Boolean = false;
 
		private var _upPressed:Boolean = false;
		private var _downPressed:Boolean = false;
		private var _leftPressed:Boolean = false;
		private var _rightPressed:Boolean = false;
 
		/**
		 * Creates Parallax Field
		 * 
		 * @param	$container		The container that holds all our starfield assets. Must be created and added to stage before being used here.
		 * @param	$x				The X position of our starfield.
		 * @param	$y				The Y position of our starfield.
		 * @param	$width			The width of our starfield.
		 * @param	height			The height of our starfield.
		 * @param	$numberOfStars	Number of stars to create.
		 * @param	$speedX			The initial X speed of our starfield.
		 * @param	$speedY			The initial Y speed of our starfield.
		 */
		public function createField($container:MovieClip, $x:int, $y:int, $width:int, $height:int, $numberOfStars:int, $speedX:int, $speedY:int):void
		{
			trace("createField");
 
			// save property references
			pathToContainer = $container;
 
			containerX = $x;
			containerY = $y;
 
			containerWidth = $width;
			containerHeight = $height;
 
			speedX = $speedX;
			speedY = $speedY;
 
			// create everything
			createStarBox();			
			addStars($numberOfStars, "small");
			addStars($numberOfStars, "normal");
			addStars($numberOfStars, "large");
 
			// enable
			enable();
		}
 
		/**
		 * Adds stars to star container
		 * 
		 * @param	$numberOfStars 	Amount of stars to create
		 */
		public function addStars($numberOfStars:int, $type:String):void
		{			
			trace("Adding stars...");
 
			var newNumberOfStars:Number;
			var graphic:String;
			var speedModifier:Number;
			var ClassReference:Class;
 
			// set star properties
			if ($type == STAR_LARGE)
			{
				graphic =  "StarLarge";
				speedModifier = 1;
				newNumberOfStars = Math.round($numberOfStars * .30);				
			}
			else if ($type == STAR_NORMAL)
			{
				graphic = "StarNormal";
				speedModifier = .66;
				newNumberOfStars = Math.round($numberOfStars * .60);
			}
			else if ($type == STAR_SMALL)
			{
				newNumberOfStars = Math.round($numberOfStars * 1);
				graphic = "StarSmall";
				speedModifier = .33;
			}
 
			trace(" type:   " + graphic);
			trace(" amount: " + newNumberOfStars);
 
			// run a for loop to create new stars (based on numberOfStars)
			var i:int;
			for (i = 0; i < newNumberOfStars; i++) 
			{
				// get class via string name
				ClassReference = getDefinitionByName(graphic) as Class;
 
				// create class
				var tempStar:MovieClip = new ClassReference();		
 
				// set random starting position
				tempStar.x = (Math.random() * (containerWidth - tempStar.width)) + containerX;
				tempStar.y = (Math.random() * (containerHeight - tempStar.height)) + containerY;
 
				// give the star its own speed modifier
				tempStar.speedModifier = speedModifier;
 
				// add new star to array that tracks all stars
				starsArray.push(tempStar);
 
				// add to display list
				pathToContainer.addChild(tempStar);
			}
 
			trace("Stars Added \n");
		}
 
		/**
		 * Activates parallax effect
		 */
		public function enable():void
		{
			if (!isStarted)
			{
				trace("Starting parallax effect...");
				isStarted = true;
 
				// add enter frame
				pathToContainer.addEventListener(Event.ENTER_FRAME, gameLoop);
			}
			else
			{
				trace("Parallax effect already running.");
			}
 
		}
 
		/**
		 * Disables parallax effect
		 */
		public function disable():void
		{
			if (isStarted)
			{
				trace("Stopping parallax effect...");
				isStarted = false;
 
				// remove enter frame
				pathToContainer.removeEventListener(Event.ENTER_FRAME, gameLoop);
			}
			else
			{
				trace("Parallax effect is not running.");
			}
 
		}
 
		/**
		 * key press getters and setters
		 */
		public function get upPressed():Boolean { return _upPressed; }
 
		public function set upPressed(value:Boolean):void 
		{
			_upPressed = value;
		}
 
		public function get downPressed():Boolean { return _downPressed; }
 
		public function set downPressed(value:Boolean):void 
		{
			_downPressed = value;
		}
 
		public function get leftPressed():Boolean { return _leftPressed; }
 
		public function set leftPressed(value:Boolean):void 
		{
			_leftPressed = value;
		}
 
		public function get rightPressed():Boolean { return _rightPressed; }
 
		public function set rightPressed(value:Boolean):void 
		{
			_rightPressed = value;
		}
 
		/*************************************************************************/
 
		/**
		 * @private
		 * Creates a star container
		 */
		private function createStarBox():void
		{
			trace("Creating star container...");
			trace(" path:   " + pathToContainer);
			trace(" x:      " + containerX);
			trace(" y:      " + containerY);
			trace(" width:  " + containerWidth);
			trace(" height: " + containerHeight);
 
			// create new container for stars
			starBox = new Sprite();			
			starBox.graphics.beginFill(0x000000);
 
			// set container's properties			
			starBox.x = containerX;
			starBox.y = containerY;
			starBox.width = containerWidth;
			starBox.height = containerHeight;
 
			// create mask
			var starBoxMask:Sprite = new Sprite();
			starBoxMask.graphics.beginFill(0xFF0000);
			starBoxMask.graphics.drawRect(containerX, containerY, containerWidth, containerHeight);
			pathToContainer.addChild(starBoxMask);
 
			// Apply mask
			starBox.mask = starBoxMask;
 
			// add starBox to stage
			pathToContainer.addChild(starBox);
 
			trace(" Container Created \n");
		}
 
		/**
		 * @private 
		 * This function is executed every frame.
		 */
		private function gameLoop(event:Event):void 
		{			
			updateSpeed();
			updateStars();
		}	
 
		/**
		 * @private
		 * This function updates the movement speed
		 */
		private function updateSpeed():void
		{
			if (upPressed)
			{
				speedY = speedY - acceleration;
			}
			else if (downPressed)
			{
				speedY += acceleration;
			}
 
			if (rightPressed)
			{
				speedX += acceleration;
			}
			else if (leftPressed)
			{
				speedX -= acceleration;
			}
		}
 
		/**
		 * @private
		 * This function updates all the objects in the stars array
		 */
		private function updateStars():void
		{
			// setting the array length variable outside of the for loop improves speed
			starArrayLength = starsArray.length;
 
			// setting the "tempStar" variable outside of the for loop improves speed
			var tempStar:MovieClip;
 
			// setting the "i" variable outside of the for loop improves speed
			var i:int;			
 
			// run for loop
			for(i = 0; i < starArrayLength; i++)
			{
				tempStar = starsArray[i];
 
				tempStar.x += speedX * tempStar.speedModifier;
				tempStar.y += speedY * tempStar.speedModifier;
 
				//Star boundres
				//check X boudries
				if (tempStar.x >= containerWidth - tempStar.width + containerX) 
				{
					//outside boundry, move to other side of container
					tempStar.x = containerX;
					tempStar.y = (Math.random() * (containerHeight - tempStar.height)) + containerY;
 
				}
				else if (tempStar.x <= containerX) 
				{
					//outside boundry, move to other side of container
					tempStar.x = containerWidth + containerX - tempStar.width;
					tempStar.y = (Math.random() * (containerHeight - tempStar.height)) + containerY;
				}
 
				//check Y boudries
				if (tempStar.y >= containerHeight - tempStar.height + containerY)
				{
					//outside boundry, move to other side of container
					tempStar.x = (Math.random() * (containerWidth - tempStar.width)) + containerX;
					tempStar.y = containerY;
				}
				else if (tempStar.y <= containerY) 
				{
					//outside boundry, move to other side of container
					tempStar.x = (Math.random() * (containerWidth - tempStar.width)) + containerX;
					tempStar.y = containerHeight + containerY - tempStar.height;
				}
			}
		}
 
	}
 
}
Download Fla Sample

Download Fla Sample

I know this script is not perfect. I might update it in the near future to use bitmaps instead of movieclips, among other things.