Free ActionScript

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

ActionScript Math and Trigonometry

Math & Trigonometry: boring but necessary to make flash games. Here is an AS3 version of my AS2 script that shows you how to calculate distance, radians, and degrees between two points (or objects).

Drag blue circle

View Code ACTIONSCRIPT
/**
 * ActionScript Math Examples
 * ---------------------
 * VERSION: 1.0
 * DATE: 12/12/2010
 * AS3
 * UPDATES AND DOCUMENTATION AT: http://www.FreeActionScript.com
 **/
package  
{
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.display.MovieClip;
	import flash.display.SimpleButton;
	import flash.geom.Rectangle;
	import flash.text.TextField;
 
	public class Main extends MovieClip
	{
		// Properties		
		public var startX:Number;
		public var startY:Number;
		public var dragging:Boolean = false;
 
		/**
		 * Constructor
		 */
		public function Main() 
		{
			trace("Main");
 
			// set center of drag area
			startX = circle.x;
			startY = circle.y;
 
			// add mouse listeners
			circle.addEventListener(MouseEvent.MOUSE_DOWN, dragPressHandler);
			stage.addEventListener(MouseEvent.MOUSE_UP, dragReleaseHandler);
 
			// make circle behave like a button (hand cursor)
			circle.buttonMode = true;
 
			// add enter frame event
			addEventListener(Event.ENTER_FRAME, enterFrameHandler);
		}
 
		/**
		 * Main loop - repeats every frame
		 * @param	event
		 */
		protected function enterFrameHandler(event:Event):void
		{
			var dx:Number = circle.x - startX;
			var dy:Number = circle.y - startY;
 
			// Calculate distance from starting point
			distanceTxt.text = String(getDistance(dx, dy));
 
			// Calculate the angle from the starting point in radians
			radiansTxt.text = String(getRadians(dx, dy));
 
			// Convert radians to degrees
			degreesTxt.text = String(getDegrees(getRadians(dx, dy)));
 
			// rotate arrow
			arrow.rotation = getDegrees(getRadians(dx, dy));
			circle.rotation = getDegrees(getRadians(dx, dy)) + 180;
 
			// Show x and y 
			xTxt.text = String(dx);
			yTxt.text = String(dy);
 
			drawLine();
		}
 
		/**
		 * Draws lines
		 */
		private function drawLine():void
		{
			// draw line from center to circle
			this.graphics.clear();
			this.graphics.lineStyle(2, 0x00CC00, .5, true);
			this.graphics.moveTo(startX, startY);
			this.graphics.lineTo(circle.x, circle.y);
 
			// draw line top to bottom
			this.graphics.lineStyle(1, 0xA2EEF7, .5, true);
			this.graphics.moveTo(circle.x, container.y);
			this.graphics.lineTo(circle.x, container.height + container.y);
 
			// draw line left to right
			this.graphics.lineStyle(1, 0xA2EEF7, .5, true);
			this.graphics.moveTo(container.x, circle.y);
			this.graphics.lineTo(container.width + container.x, circle.y);
		}
 
		/**
		 * Mouse Press handler
		 * @param	event
		 */
		protected function dragPressHandler(event:MouseEvent):void
		{
			// Create a rectangle to constrain the drag
			var rx:Number = container.x + circle.width/2;
			var ry:Number = container.y + circle.height/2;
			var rw:Number = container.width - circle.width;
			var rh:Number = container.height - circle.height;
			var rect:Rectangle = new Rectangle(rx, ry, rw, rh);
 
			dragging = true;
			circle.startDrag(false,rect);
		}
 
		/**
		 * Mouse Release handler
		 * @param	event
		 */
		protected function dragReleaseHandler(event:MouseEvent):void
		{
			if (dragging)
			{
				dragging = false;
				circle.stopDrag();
			}
		}
 
		/**
		 * Get distance
		 * @param	delta_x
		 * @param	delta_y
		 * @return
		 */
		public function getDistance(delta_x:Number, delta_y:Number):Number
		{
			return Math.sqrt((delta_x*delta_x)+(delta_y*delta_y));
		}
 
		/**
		 * Get radians
		 * @param	delta_x
		 * @param	delta_y
		 * @return
		 */
		public function getRadians(delta_x:Number, delta_y:Number):Number
		{
			var r:Number = Math.atan2(delta_y, delta_x);
 
			if (delta_y < 0)
			{
				r += (2 * Math.PI);
			}
			return r;
		}
 
		/**
		 * Get degrees
		 * @param	radians
		 * @return
		 */
		public function getDegrees(radians:Number):Number
		{
			return Math.floor(radians/(Math.PI/180));
		}
	}
 
}
Download Fla Sample

Download Fla Sample

Flying Through Space

Simple “Flying Through Space” AS3 effect.

Usage:
starField.createField(container, x, y, width, height, numberOfStars);

Download Fla Sample

Download Fla Sample

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 &amp; 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 &lt; speedMax) 				{ 					//speed up 					speed += speedAcceleration; 					//check if above speedMax 					if (speed &gt; speedMax)
					{
						//reset to speedMax
						speed = speedMax;
					}
				}
			}
 
			if (down)
			{
				//check if below speedMaxReverse
				if (speed &gt; speedMaxReverse)
				{
					//speed up (in reverse)
					speed -= speedAcceleration;
					//check if above speedMaxReverse
					if (speed &lt; speedMaxReverse) 					{ 						//reset to speedMaxReverse 						speed = speedMaxReverse; 					} 				} 			} 			 			if (left) 			{ 				//turn left 				steering -= steeringAcceleration; 				//check if above steeringMax 				if (steering &gt; steeringMax)
				{
					//reset to steeringMax
					steering = steeringMax;
				}
			}
 
			if (right)
			{
				//turn right
				steering += steeringAcceleration;
				//check if above steeringMax
				if (steering &lt; -steeringMax) 				{ 					//reset to steeringMax 					steering = -steeringMax; 				} 			} 			 			// friction     			speed *= groundFriction; 			 			// prevent drift 			if(speed &gt; 0 &amp;&amp; speed &lt; 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 &gt; 0)
			{
				// check if steering value is really low, set to 0
				if(steering &lt; 0.05)
				{
					steering = 0;
				}
			}
			// prevent steering drift (left)
			else if(steering &lt; 0) 			{ 				// check if steering value is really low, set to 0 				if(steering &gt; -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.