Friday, April 29, 2011

Using hit-test bouncing ball in action script 3

I have this code which makes the ball bounce, but what I am looking for is to shoot bullets from the ground and once they hit the ball they should bounce it back upwards. The goal is not to let the ball hit the ground. I am sure this has been done before, but I guess am too dumb to figure it out.

The Code:

package {

public class ball extends MovieClip {

 var timer:Number=0;
 var initialPos:Number=0;
 var finalPos:Number=0;
 var currentPos:Number=0;
 var initialSpeed:Number=0;




 function ball() {

  startFallingBall();
 }

 function moveBallDown(e:Event) {
  timer+=1;

  this.y = initialPos + .5 *(timer * timer);
  checkBottomBoundary();
 }

 function moveBallUp(e:Event) {
  timer+=1;

  var posA=this.y;

  this.y = currentPos - initialSpeed*timer + .5*(timer * timer);

  var posB=this.y;

  checkTopBoundary(posA, posB);
 }

 function checkBottomBoundary() {
  if (this.y+this.height>stage.stageHeight) {
   finalPos=this.y;

   stopFallingBall();
  }
 }

 function checkTopBoundary(firstPos:Number, secondPos:Number) {
  if (secondPos>firstPos) {
   stopRisingBall();
   startFallingBall();
  }
 }

 function startFallingBall() {
  timer=0;
  initialPos=this.y;
  this.addEventListener(Event.ENTER_FRAME, moveBallDown);
 }

 function stopFallingBall() {
  this.removeEventListener(Event.ENTER_FRAME, moveBallDown);


  if (finalPos-initialPos<.1*this.height) {
   stopRisingBall();
  } else {
   startRisingBall();
  }
 }

 function startRisingBall() {
  initialSpeed=Math.sqrt(Math.abs(finalPos-initialPos));
  timer=0;

  currentPos=this.y;

  this.addEventListener(Event.ENTER_FRAME, moveBallUp);
 }

 function stopRisingBall() {
  this.removeEventListener(Event.ENTER_FRAME, moveBallUp);
 }

 function stopEverything() {
  this.removeEventListener(Event.ENTER_FRAME, moveBallUp);
  this.removeEventListener(Event.ENTER_FRAME, moveBallDown);
 }
}

}

From stackoverflow
  • There's a function for preforming hittest you can read about it here: http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/display/DisplayObject.html#hitTestObject()

    Though with circles it's pretty easy if you know the radius, if the distance between the centers is less than the sum of their radii; they touch each other.

    But by looking at your code you should properly rewrite the whole thing. The ball really should not handle collision and movement logic internally. It should only have a positon and speed vector, and the movement and colission logic should be in other classes.

    As for the code for reaction, it depends on how complicated you want it. And can be anthing from simply flipping the y part of the speed vector, to fairly complicated math.

    There's alot of toturial and examples in this area, I think you would be better of finding some on google and playing with it. Then write your own.

  • A simple way is to use DisplayObject's hitTestObject. This checks for overlapping. You can of course write something more advanced yourself.

    For each game update you check if any bullets hit the ball, and take action if they did. You should also consider separating game logic and display updating. Look into using Timer.

    package {
        public class BallGame extends Sprite
        {
            private var ball:Ball;
            private var bullets:Array;
    
            public function BallGame() {
             addEventListener(Event.ENTER_FRAME, checkCollision);
             addEventListener(MouseEvent.CLICK, fireBullet);
            }
    
            private function fireBullet(e:MouseEvent):void {
             // adds a fired bullet to an array so we can loop over all bullets
             bullets.push(new Bullet());
            }
    
            private function checkCollision(e:Event):void {
             // loops through all bullets in play
             for each(var bullet:Bullet in bullets) {
                 // check if the bullet is inside the ball
                 if (ball.hitTestObject(bullet)) {
                  // the bullet hit the ball
                  ball.startRisingBall();
    
                  // TODO: remove the bullet :)
                 }
             }
            }
        }
    }
    

0 comments:

Post a Comment