Results 1 to 4 of 4

Thread: OOP: Balls bouncing off each other, resting on each other.

  1. #1

    OOP: Balls bouncing off each other, resting on each other.

    Hi guys, I've been trying to recreate the yugop example(www.yugop.com) where the balls seem to bounce off each other, but the difference is, they can also rest on top of each other. I've included my example and the class for help.

    Thanks.

    click to add more balls.

    SWF: http://www.fuzzfolio.com/workarea/myBallYugop.html

    Code:
    main.fla
     
    var ballcount:Number=1;
    var ballSet:Array = new Array();
     
    for (i = 0; i < ballcount; i++){ 
     ballSet[i] = new myBallDynamics(i,_root);
     ballSet[i].bounceAround();
    } 
     
    mybox.onPress=function(){
     mybox.onRollOut();
     ballSet[ballcount] = new myBallDynamics(ballcount,_root);
     ballSet[ballcount].startBallScale();
     
          mybox.onMouseMove=function(){
               ballSet[ballcount].followCursor();
          }
     
          mybox.onRollOut=function(){
              mybox.onMouseMove=null;
              ballSet[ballcount].stopBallScale();
              ballSet[ballcount].bounceAround();
              ballcount=ballcount+1;
          };
    };
     
    mybox.onRelease=function(){
             mybox.onMouseMove=null;
             mybox.onRollOut=null;
     
             ballSet[ballcount].stopBallScale();
             ballSet[ballcount].bounceAround();
             ballcount=ballcount+1;
    };
     
    stop();
    my class
    Code:
    class myBallDynamics{
     public var bid:Number;
     
     private var ballX:Number;
     private var ballY:Number;
     private var velX:Number;
     private var velY:Number;
     
     private var gravity:Number = 0;
     private var boundaries:Object;
     
     private var parentHolder:MovieClip;
     private var holder:MovieClip;
     
     private var radius:Number;
     private var mass:Number;
     
     function myBallDynamics(numOfBalls:Number, parentMC:MovieClip){ 
      bid = numOfBalls;
      parentHolder = parentMC;
      holder = parentHolder.attachMovie("ball", "ball"+numOfBalls, numOfBalls,{_x:150, _y:150}); 
     
      init(10);
     }
     
     function init(pgravity:Number){
      gravity = pgravity;
      radius = holder._width / 2;
      mass = radius;
     
      velX = Math.random()*20-10; 
      velY = -Math.random()*20;
     
      ballX = holder._x; 
      ballY = holder._y; 
     
      checkForWalls();
     }
     
     function getMass(){
      return mass;
     }
     
     function getX(){
      return holder._x;
     }
     
     function getY(){
      return holder._y;
     }
     
     function getVX(){
      return velX;
     }
     
     function getVY(){
      return velY;
     }
     
     function getBX(){
      return ballX;
     }
     
     function getBY(){
      return ballY;
     }
     
     function setVX(newVX:Number){
      velX = newVX;
     }
     
     function setVY(newVY:Number){
      velY = newVY;
     }
     
     function setBX(newBX:Number){
      ballX = newBX;
     }
     
     function setBY(newBY:Number){
      ballY = newBY;
     }
     
     function getWidth(){
      return holder._width;
     }
     
     function getHeight(){
      return holder._height;
     }
     
     function setWidth(newWidth:Number){
      holder._width = newWidth;
     }
     
     function setHeight(newHeight:Number){
      holder._heifht = newHeight;
     }
     
     function setX(newX:Number){
      holder._x = newX;
     }
     
     function setY(newY:Number){
      holder._y = newY;
     }
     
     function getRadius(){
      return radius;
     }
     
     function followCursor(){
      holder._x = _root._xmouse;
      holder._y = _root._ymouse;
     }
     
     function startBallScale(){
      followCursor();
     
      var dir:Number=5;
      holder.onEnterFrame=function(Void):Void{
       if (this._width >= 100){
        dir=-5;
       }
       if(this._height <= 25){
        dir=5;
       }
     
       this._width += dir;
       this._height += dir;
      }
     }
     
     function stopBallScale(){
      radius = holder._width / 2;
      holder.onEnterFrame=null;
     }
     
     function updateMovement(){
        // render our new position
            holder._x = ballX;
            holder._y = ballY;
            updateAfterEvent();
     }
     
     function bounceAround(){
      holder['obj']=this;
      holder.onEnterFrame=function(Void):Void { 
       this.obj.ballX = this._x;
       this.obj.ballY = this._y;
     
       this.obj.velY += this.obj.gravity;
     
       //this.obj.ballX += this.obj.velX; 
       this.obj.ballY += this.obj.velY; 
     
       this.obj.checkForWalls();
       this.obj.checkForBalls();
       this.obj.updateMovement();
      }
     
     }  
     
     function checkForWalls():Void {
           // top
           if (ballY - radius < 0) {
               ballY = radius;
     
               velY *= -1;
           }
           // bottom
           else if (ballY + radius > Stage.height) {
               ballY = Stage.height - radius;
               velY *= -1;
           }
           // left
           if (ballX - radius < 0) {
               ballX = radius;
         if(velX > 0 ) {
             velX = velX - 1;
         } else {
          velX = velX + 1;
         }
               velX *= -1;   
           }
           // right
           else if (ballX + radius > Stage.width) {
               ballX = Stage.width - radius;
         if(velX > 0 ) {
             velX = velX - 1;
         } else {
          velX = velX + 1;
         }
         velX *= -1;
     
        }
        }
     
     
        function checkForBalls():Void {
            // Have a look at the other balls on the stage and see if
            // we're hitting them.  If so, react accordingly.
     
            // shortcut to the array that knows about all of the Balls on
            // the stage
            var allBalls:Array = parentHolder.ballSet; 
            // for each of the balls on the stage
            for (var i = 0; i < allBalls.length; i++) {
            // if our bid is less than theirs
            // (this makes sure that each ball only looks for a collision
            // with each other ball once per frame)
            // If you ever delete balls - make sure you reset all the bids
             if (allBalls[i].bid > bid) {
                // figure out how far away we are from them
                // distance on the x axis
                   var xdiff:Number = allBalls[i].getBX() - ballX;
                // distance on the y axis
                   var ydiff:Number = allBalls[i].getBY() - ballY;
                // use pythagoras' magic
                   var dist:Number = Math.sqrt(xdiff * xdiff + ydiff * ydiff);
     
                   // hit test is easy with circles
                   // if dist <= sum of radii, we're hitting
                   if (dist <= (radius + allBalls[i].getRadius())) {
                       // we're hitting, call the reaction function
                       ballBallReaction(this, allBalls[i], dist, xdiff, ydiff);
                   }
                 }
             }
         }
     
     
         function ballBallReaction(b1:myBallDynamics, b2:myBallDynamics, dist:Number, xdiff:Number, ydiff:Number):Void {
      // params
         //            b1 - first ball in collision
         //            b2 - second ball in collision
         //            dist - distance between the middle of the two balls
         //            xdiff - diff between balls on the x axis
         //            ydiff - diff between balls on the y axis
     
         // This function is where the billiard goodness takes place.
         // It's physics madness... I'll explain the bits I think I understand
     
         // find the angle between the balls
            var angle = Math.atan2(ydiff, xdiff);
     
            var cosa = Math.cos(angle);
            var sina = Math.sin(angle);
     
         // find the current linear momentum on each axis for each ball
         // I think this rotates the coordinate system so that we can
         // determine a 2 dimensional collision
            var vx1p = cosa * b1.getVX() + sina * b1.getVY();
            var vy1p = cosa * b1.getVY() - sina * b1.getVX();
            var vx2p = cosa * b2.getVX() + sina * b2.getVY();
            var vy2p = cosa * b2.getVY() - sina * b2.getVX();
     
         // P = momentum?
         // V = velocity?
            var P = vx1p * b1.getMass() + vx2p * b2.getMass();
            var V = vx1p - vx2p;
     
            vx1p = (P - b2.getMass() * V)/(b1.getMass() + b2.getMass());
            vx2p = V + vx1p;
     
         // tell each ball how fast they're going on each axis
            b1.setVX(cosa * vx1p - sina * vy1p);
            b1.setVY(cosa * vy1p + sina * vx1p);
            b2.setVX(cosa * vx2p - sina * vy2p);
            b2.setVY(cosa * vy2p + sina * vx2p);
     
         // Work out the where the balls are colliding along the
         // "Line of Action" so that we can project them far enough
         // away from each other to no longer intersect
            var diff = ((b1.getRadius() + b2.getRadius()) - dist) / 2;
     
            var cosd = cosa * diff;
            var sind = sina * diff;
     
         // update their temporary positions
            b1.setBX(b1.getBX()- cosd);
            b1.setBY(b1.getBY()- sind);
            b2.setBX(b2.getBX()+ cosd);
            b2.setBY(b2.getBY()+ sind);
        }
    }
    Last edited by fuzzyfluid; January 1st, 2007 at 07:04 PM.

  2. #2
    TheCanadian's Avatar
    10,300
    posts
    Noo doot aboot it, eh?
    So, do you have a question?
    Proud Montanadian
    We tolerate living and breathing. And niches.

    Name Brand Watches

    Maybe getTimer() or TweenMax is the answer to your problem . . .

  3. #3
    yeah, sorry bout that. Just by testing out the example, you would see that adding balls, they seem to disappear off the stage and the balls don't rest on each other correctly. I'd like the balls to be able to rest on each other, but im having troubling getting it to work correctly.

    so I guess the question is: how do i get the balls to lie on top of each other once the stage floor is filled with balls?

  4. #4
    still havent solved this little experimental problem im having.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

Home About kirupa.com Meet the Moderators Advertise

 Link to Us

 Credits

Copyright 1999 - 2012