Free ActionScript

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

Simple Physics with Friction & Gravity

Adding gravity to a ball from my previous Simple Physics with Friction AS3 example.

This script creates a ball and makes it bounce around in a container, as a real ball would. The ball slows down over time and comes to a stop due to friction and gravity.

Click ball to reset speed

View Code ACTIONSCRIPT
/**
 * Simple Physics with Friction & Gravity
 * ---------------------
 * VERSION: 1.2
 * DATE: 11/28/2010
 * AS3
 * UPDATES AND DOCUMENTATION AT: http://www.FreeActionScript.com
 **/
package com.freeactionscript
{
	import flash.display.DisplayObjectContainer;
	import flash.display.MovieClip
	import com.freeactionscript.Ball;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;
 
	public class SimplePhysics
	{
		// reference to container (stage, movieclip or sprite)
		private var _canvas:DisplayObjectContainer;
 
		// ball object
		private var _ball:Ball;
 
		// boundries
		private var _boundries:Rectangle;
		private var _minX:int;
		private var _minY:int;
		private var _maxX:int;
		private var _maxY:int;
 
		// settings
		private var _friction:Number = .98;
		private var _gravity:Number = .68;
 
		/**
		 * Constructor
		 * @param	$canvas	Takes DisplayObjectContainer (MovieClip, Sprite, Stage) as argument
		 */
		public function SimplePhysics($canvas:DisplayObjectContainer)
		{
			trace("SimplePhysics");
 
			_canvas = $canvas;
 
			setBoundries(_canvas);
			createBall(_canvas);
			enable();
		}
 
		/**
		 * Creates ball
		 */
		private function createBall($container:DisplayObjectContainer):void
		{
			// get random number between -10 and 10
			var newRandomX:Number = Math.random() * 20 - 20;
			var newRandomY:Number = Math.random() * 20 - 30;
 
			// Create new ball. Usage: new Ball(x, y, velocity X, velocity Y);
			_ball = new Ball(150, 200, newRandomX, newRandomY);
 
			// add mouse listener to ball
			_ball.addEventListener(MouseEvent.CLICK, onBallClick);
			_ball.buttonMode = true;
 
			//
			$container.addChild(_ball);
		}
 
		/**
		 * On ball CLICK handler
		 * @param	$even	Takes MouseEvent
		 */
		private function onBallClick($event:MouseEvent):void
		{
			resetBall(Ball($event.target));
		}
 
		/**
		 * Enables physics engine
		 */
		private function enable():void
		{
			_canvas.addEventListener(Event.ENTER_FRAME, update);
		}
 
		/**
		 * Disables physics engine
		 */
		public function disable():void
		{
			_canvas.removeEventListener(Event.ENTER_FRAME, update);
		}
 
		/**
		 * Resets ball's volocity
		 * @param	$ball	Takes Ball object
		 */
		public function resetBall($ball:Ball):void
		{
			// get random number between -10 and 10
			var newRandomX:Number = Math.random() * 20 - 20;
			var newRandomY:Number = Math.random() * 20 - 30;
 
			// update ball velocity
			$ball.velocityX = newRandomX;
			$ball.velocityY = newRandomY;
		}
 
		/**
		 * Sets container boundries
		 */
		public function setBoundries($container:DisplayObjectContainer):void
		{
			_boundries = new Rectangle(0, 0, $container.width, $container.height);
			_minX = 0;
			_minY = 0;
			_maxX = $container.width;
			_maxY = $container.height;
		}
 
		/**
		 * Update function that updates ball
		 * @param	$event
		 */
		private function update($event:Event):void
		{
			// Check X
			// Check if we hit top
			if (((_ball.x - _ball.width / 2) <= _minX) && (_ball.velocityX < 0)) 			{ 				_ball.velocityX = -_ball.velocityX; 			} 			// Check if we hit bottom 			if ((_ball.x + _ball.width / 2) >= _maxX && (_ball.velocityX > 0))
			{
				_ball.velocityX = -_ball.velocityX;
			}
 
			// Check Y
			// Check if we hit left side
			if (((_ball.y - _ball.height / 2) <= _minY) && (_ball.velocityY < 0)) 			{ 				_ball.velocityY = -_ball.velocityY 			} 			// Check if we hit right side 			if (((_ball.y + _ball.height / 2) >= _maxY) && (_ball.velocityY > 0))
			{
				_ball.velocityY = -_ball.velocityY;
			}
 
			// apply friction to ball velocity
			_ball.velocityX *= _friction;
			_ball.velocityY *= _friction;
 
			// apply gravity (only to Y axis)
			_ball.velocityY += _gravity;
 
			// Update X
			// Update position
			_ball.x += _ball.velocityX;
 
			// Update Y
			// Make sure we dont fall thru the bottom
			if ((_ball.y + _ball.velocityY + (_ball.height / 2)) > _maxY)
			{
				// if we're falling thru, set ball y at maxY, minus ball size
				_ball.y = _maxY - (_ball.height / 2);
			}
			else
			{
				// update position
				_ball.y += _ball.velocityY;
			}
 
		}
	}
}

Only a couple of small changes were made to the original script.

Added a gravity variable:

private var _gravity:Number = .68;

Add gravity to Y velocity:

_ball.velocityY += _gravity;

And make sure the ball doesn’t fall through the floor:

if ((_ball.y + _ball.velocityY + (_ball.height / 2)) > _maxY)
{
_ball.y = _maxY - (_ball.height / 2);
}
else
{
_ball.y += _ball.velocityY;
}

Download Fla Sample

Download Fla Sample

See how to make multiple balls collide and bounce off each other.

Simple Physics with Friction

We are going to extend my previous Simple Physics AS3 script by adding friction to the ball.

This script creates a ball and makes it bounce around in a container, changing direction when a wall is hit. The ball slows down over time due to friction.

Click ball to reset speed

View Code ACTIONSCRIPT
/**
 * Simple Physics with Friction
 * ---------------------
 * VERSION: 1.1
 * DATE: 11/21/2010
 * AS3
 * UPDATES AND DOCUMENTATION AT: http://www.FreeActionScript.com
 **/
package com.freeactionscript
{
	import flash.display.DisplayObjectContainer;
	import com.freeactionscript.Ball;
	import flash.events.Event;
	import flash.events.MouseEvent;
 
	public class SimplePhysics
	{
		// reference to container (stage, movieclip or sprite)
		private var _canvas:DisplayObjectContainer;
 
		// ball object
		private var _ball:Ball;
 
		// boundries
		private var _minX:int;
		private var _minY:int;
		private var _maxX:int;
		private var _maxY:int;
 
		// settings
		private var _friction:Number = .98;
 
		/**
		 * Constructor
		 * @param	$canvas	Takes DisplayObjectContainer (MovieClip, Sprite, Stage) as argument
		 */
		public function SimplePhysics($canvas:DisplayObjectContainer)
		{
			trace("SimplePhysics");
 
			_canvas = $canvas;
 
			setBoundries(_canvas);
			createBall(_canvas);
			enable();
		}
 
		/**
		 * Creates ball
		 */
		private function createBall($container:DisplayObjectContainer):void
		{
			// get random number between -10 and 10
			var newRandomX:Number = Math.random() * 10 - 10;
			var newRandomY:Number = Math.random() * 10 - 10;
 
			// Create new ball. Usage: new Ball(x, y, velocity X, velocity Y);
			_ball = new Ball(150, 200, newRandomX, newRandomY);
 
			// add mouse listener to ball
			_ball.addEventListener(MouseEvent.CLICK, onBallClick);
 
			//
			$container.addChild(_ball);
		}
 
		/**
		 * On ball click handler
		 * @param	$even	Takes MouseEvent
		 */
		private function onBallClick($even:MouseEvent):void 
		{
			resetBall(Ball($even.target));
		}
 
		/**
		 * Enables physics engine
		 */
		private function enable():void
		{
			_canvas.addEventListener(Event.ENTER_FRAME, update);
		}
 
		/**
		 * Disables physics engine
		 */
		public function disable():void
		{
			_canvas.removeEventListener(Event.ENTER_FRAME, update);
		}
 
		/**
		 * Resets ball's volocity
		 * @param	$ball	Takes Ball object
		 */
		public function resetBall($ball:Ball):void
		{
			// get random number between -10 and 10
			var newRandomX:Number = Math.random() * 20 - 20;
			var newRandomY:Number = Math.random() * 20 - 20;
 
			// update ball velocity
			$ball.velocityX = newRandomX;
			$ball.velocityY = newRandomY;
		}
 
		/**
		 * Sets container boundries
		 */
		public function setBoundries($container:DisplayObjectContainer):void
		{
			_minX = 0;
			_minY = 0;
			_maxX = $container.width;
			_maxY = $container.height;
		}
 
		/**
		 * Update function that updates ball
		 * @param	$event
		 */
		private function update($event:Event):void 
		{
			// Check X
			// Check if we hit top
			if (((_ball.x - _ball.width / 2) < _minX) && (_ball.velocityX < 0))
			{
			  _ball.velocityX = -_ball.velocityX;
			}
			// Check if we hit bottom
			if ((_ball.x + _ball.width / 2) > _maxX && (_ball.velocityX > 0))
			{
			  _ball.velocityX = -_ball.velocityX;
			}
 
			// Check Y
			// Check if we hit left side
			if (((_ball.y - _ball.height / 2) < _minY) && (_ball.velocityY < 0))
			{
			  _ball.velocityY = -_ball.velocityY
			}
			// Check if we hit right side
			if (((_ball.y + _ball.height / 2) > _maxY) && (_ball.velocityY > 0))
			{
			  _ball.velocityY = -_ball.velocityY;
			}
 
			// apply friction to ball velocity
			_ball.velocityX *= _friction;
			_ball.velocityY *= _friction;
 
			// update ball position
			_ball.x += _ball.velocityX;
			_ball.y += _ball.velocityY;
		}
	}
}

Here is how the previous AS3 physics example was changed to add friction.

We add a friction variable:

private var _friction:Number = .98;

And then we apply friction to the ball velocity:

_ball.velocityX *= _friction;
_ball.velocityY *= _friction;

That’s all there’s to it.

Download Fla Sample

Download Fla Sample

In the next example, we will add Gravity.