Colliding balls, any ways to improve efficiency?

Hi,

I’m quite new to as3 and could do with some help making improvements on some code I’ve wrote.

I have 50 balls colliding on screen and the program seems to run quite smoothly. If I increase the amount of balls to 150 the movie gets a bit slow.

I have a feeling that improvements can be made on the HandleCollisions function as it currently loops through every ball to see if a collision is taking place. Also I have used Math.sin() to give the balls a slight wavy movement(not sure if this can be improved on).

I’m looking for any ideas on how to make it more efficient so it will run smoothly with 150 balls.

Any comments welcome, even if it’s about general layout and best practises.

Here is my ball class:

package {
 import flash.events.*;
 import flash.display.*;
 import flash.display.MovieClip;
 import flash.display.DisplayObject;
 import flash.geom.Matrix;
 
 public class Ball extends MovieClip{
  static public const maxWidth:int = 20;    // max width of a ball.
  static public const minWidth:int = 6;    // min width of a ball.
  static public const maxSpeed:Number = 2.2;   // max width of a ball.
  static public const minSpeed:Number = 1;   // min width of a ball.
 
  static public var ballList:Array = new Array;  // instances of the ball class.
  static public var stageW:int,stageH:int;   // size of the stage.
 
  public var forceX:Number;
  public var forceY:Number;
 
  public var ballRadius:Number, ballWidth:Number;
  public var motionCount:Number;
  static var pie2:Number = Math.PI*2;
 
  // The following variables are used in the handle colisions function.
  static public var ballListLength:int;
  static public var xDist:Number;
  static public var yDist:Number;
  static public var dist:Number;
  static public var diff:Number;
  static public var angle:Number;
  static public var totalWidth:Number;
  static public var otherBallX:Number;
  static public var otherBallY:Number;
  static public var currentBallY:Number;
  static public var currentBallX:Number;
 
 
  public function Ball(){
 
   ballWidth = Math.round(Math.random() * (maxWidth - minWidth)) + minWidth;
   ballRadius = ballWidth/2;
 
   motionCount = Math.random()*pie2;
 
   x = ballRadius+Math.random()*(stageW-ballWidth);
   y = ballRadius+Math.random()*(stageH-ballWidth);
 
   if (Math.random()<0.5){
    forceY = minSpeed+Math.random()*(maxSpeed - minSpeed);
   }else{
    forceY = -minSpeed-Math.random()*(maxSpeed - minSpeed);
   }
   graphics.beginFill(Math.random()*0xFFFFFF); 
   graphics.drawCircle(0,0, ballWidth); 
   graphics.endFill();
 
   addEventListener(Event.ENTER_FRAME, HandleCollisions);
 
   ballList.push(this);
  }
 
  public function HandleCollisions(e:Event):void{
   MoveBall();
 
   ballListLength = ballList.length;
 
   for (var i=0; i< ballListLength; i++){
    otherBallX   = ballList*.x;
    currentBallX  = x;
    otherBallY  = ballList*.y; 
    currentBallY  = y;
 
    if ( (this != ballList*) && (hitTestObject(ballList*)) ){
 
     xDist = currentBallX - otherBallX;
     yDist = currentBallY - otherBallY;
     dist = Math.sqrt((xDist * xDist) + (yDist * yDist));
     totalWidth = ballWidth+ballList*.ballWidth;
     diff = dist-totalWidth;
     if (diff<0){
      //colliding
      angle = Math.atan2(yDist, xDist);
 
      x = otherBallX + ((totalWidth) * Math.cos(angle));
      y = otherBallY + ((totalWidth) * Math.sin(angle));
     }
    }
   }
  }
  public function MoveBall():void{
 
   if (motionCount<pie2){
    forceX = Math.sin(motionCount)/2;
    motionCount+= 0.06;
   }else{
    motionCount = 0;
   }
 
   if (x-ballWidth>stageW){
    x = 0-ballWidth;
   } else if (x+ballWidth<0){
    x = stageW+ballWidth;
   }
 
   x = x + forceX;
   y = y + forceY;
   if ((y>stageH+ballWidth+50)||(y<-50-ballWidth)){
    Restart();
   }
  }
  public function Restart():void{
   if (forceY > 0) {
    y = -40;
   } else {
    y = stageH+40;
   }
  }
 }
}