Free ActionScript

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

Simple Physics with Friction & Gravity

4 Comments »

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.

4 Responses

[...] the next example, we will add Gravity. Game Examples AS3, PhysicsActionScript 3, ball physics with friction, [...]

  • Why does the ball always go to the right when you click it???

  • littlenight,

    var newRandomX:Number = Math.random() * 20 – 20;

    means that the ball is almost always going to go left.

    Try using this instead:
    var newRandomX:Number = Math.random() * 20 – 10;

  • Leave a Reply

    You must be logged in to post a comment.