title: Collision-based springing
body: <p>I have placed one large ball, "centerBall", in the center of the stage. Then I added in a
  bunch of smaller ones, giving them random sizes and velocities. These will move with basic motion code and bounce off the walls. On each frame, did a distance-based collision check between each moving ball and the center ball. If I got a collision, I've calculated an offset spring target based on the angle between the two balls and the minimum distance. 
  There is still one problem: some of the smaller balls bypass "centerBall" boundaries and then bounce off. You can see that in the attached image. Why is happening this?
  Here is the code:</p>
  
  <pre><code>import flash.display.Sprite;
  import flash.events.Event;
  
  public class Bubbles extends Sprite
  {
      private var balls:Array;
      private var numBalls:Number = 10;
      private var centerBall:Ball;
      private var bounce:Number = -1;
      private var spring:Number = 0.2;
  
      public function Bubbles()
      {
          init();
      }
  
      private function init():void
      {
          balls = new Array();
          centerBall = new Ball(100, 0xcccccc);
          addChild(centerBall);
          centerBall.x = stage.stageWidth / 2;
          centerBall.y = stage.stageHeight / 2;
  
          for(var i:uint = 0; i &lt; numBalls; i++)
          {
              var ball:Ball = new Ball(Math.random() * 40 + 5, Math.random() * 0xffffff);
              ball.x = Math.random() * stage.stageWidth;
              ball.y = Math.random() * stage.stageHeight;
              ball.vx = Math.random() * 6 - 3;
              ball.vy = Math.random() * 6 - 3;
              addChild(ball);
              balls.push(ball);
          }
  
          addEventListener(Event.ENTER_FRAME, onEnterFrame);          
      }
  
      private function onEnterFrame(event:Event):void
      {
          for(var i:uint = 0; i &lt; numBalls; i++)
          {
              var ball:Ball = balls[i];
              move(ball);
              var dx:Number = ball.x - centerBall.x;
              var dy:Number = ball.y - centerBall.y;
              var dist:Number = Math.sqrt(dx * dx + dy * dy);
              var minDist:Number = ball.radius + centerBall.radius;
              if(dist &lt; minDist)
              {
                  var angle:Number = Math.atan2(dy, dx);
                  var targetX:Number = centerBall.x + Math.cos(angle) * minDist;
                  var targetY:Number = centerBall.y + Math.sin(angle) * minDist;
                  ball.vx += (targetX - ball.x) * spring;
                  ball.vy += (targetY - ball.y) * spring;
              }
          }
      }
  
      private function move(ball:Ball):void
      {
          ball.x += ball.vx;
          ball.y += ball.vy;
          if(ball.x + ball.radius &gt; stage.stageWidth)
          {
              ball.x = stage.stageWidth - ball.radius;
              ball.vx *= bounce;
          }
          else if(ball.x - ball.radius &lt; 0)
          {
              ball.x = ball.radius;
              ball.vx *= bounce;
          }
          if(ball.y + ball.radius &gt; stage.stageHeight)
          {
              ball.y = stage.stageHeight - ball.radius;
              ball.vy *= bounce;
          }
          else if(ball.y - ball.radius &lt; 0)
          {
              ball.y = ball.radius;
              ball.vy *= bounce;
          }
      }
  }
  </code></pre>
  
  <p><a href="http://imageshack.us/photo/my-images/14/screenshotazp.jpg/" rel="nofollow">Click here to see the pic</a></p>