Free ActionScript

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

Physics – Multiple objects (balls) colliding

After months and months of trying to figure this one out, I finally managed to build a fully working example!

So, here is the first version of my Simple Physics script – multiple balls colliding and bouncing off each other.

Preview

Download Fla Sample

Download Fla Sample

I have to give credit to a book called HTML5 Canvas by Steve Fulton & Jeff Fulton (great book!). It was very hard to grasp the law of conservation of momentum without it. Thanks guys!

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.

Simple Physics

Very simple flash physics in AS3. This script creates a ball and makes it bounce around in a container, changing direction when a wall is hit.

View Code ACTIONSCRIPT
/**
 * Simple Physics
 * ---------------------
 * 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;
 
	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;
 
		/**
		 * 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;
 
			//Ball usage: new Ball(x, y, velocity X, velocity Y);
			_ball = new Ball(150, 200, newRandomX, newRandomY);
			$container.addChild(_ball);
		}
 
		/**
		 * 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);
		}
 
		/**
		 * 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;
			}
 
			// update ball position
			_ball.x += _ball.velocityX;
			_ball.y += _ball.velocityY;
		}
	}
}
Download Fla Sample

Download Fla Sample

Find out how to add friction in the next example.