Search code examples
actionscript-3flashcollisionbreakout

Breakout with Flash: I need help to improve my Brick n Ball collision


I've been stuck on this problem for a very long time now, I've searched around alot and tried stuff, but nothing works. Some explanations are just very hard for me to understand as Im pretty new to programming overall and got alot to learn.

I have two problems

1: The ball wont collide with the bricks sometimes when the speed is too fast.

2: The ball is capable of hitting 2 bricks. Both problems is related to the fact that 60 fps isnt enough for my type of collision detection to work properly.

I just need someone to explain in a simple way as possible what I need to do to make a collision detection that will prevent this from happen.

Here's my current collision code:

private function checkCollision(): void {
  grdx = Math.floor((ball.x) / 28);
  grdy = Math.floor((ball.y) / 14);
  ngrdx = Math.floor((ball.x + dx) / 28);
  ngrdy = Math.floor((ball.y + dy) / 14);
  var flipX: Boolean = false;
  var flipY: Boolean = false;
  if ((grdy <= level.length - 1) && 
      (ngrdy <= level.length - 1) && 
      (grdy >= 0 && ngrdy >= 0)) {
    if (testBlock(grdx, ngrdy)) {
      flipY = true;
      paddleFlag = 1;
    }
    if (testBlock(ngrdx, grdy)) {
      flipX = true;
      paddleFlag = 1;
    }
    if (testBlock(ngrdx, ngrdy)) {
      flipX = true;
      flipY = true;
      paddleFlag = 1;
    }
    dx *= flipX ? -1 : 1;
    dy *= flipY ? -1 : 1;
  }
}
private function testBlock(xPos: int, yPos: int): Boolean {
  if (level[yPos][xPos] > 0 && level[yPos][xPos] != 13) {
    trace("hit on X,Y");
    level[yPos][xPos] = 0;
    breakBlock("Block_" + yPos + "_" + xPos);
    trace("Block: " + totalBreaks + " / " + totalBlocks);
    return true;
  }
  return false;
}
private function breakBlock(blockName: String): void {
  if (this.getChildByName(blockName)) {
    this.removeChild(this.getChildByName(blockName));
    totalBreaks++;
  }
}

Thank you and sorry for my bad english, its not my motherlanguage.


Solution

  • One solution is to move the ball in smaller iterations, multiple times in a given frame.

    For example, and I am giving this solution assuming that you are moving the ball based on the time elapsed from the last frame.

    Suppose that 30 milliseconds have elapsed since the last frame update. In that case you would update the movement/collision twice in that frame using 15 millisecond as your time elapsed.

    The higher resolution of collision you want, the more iterations you would do.

    Here's an example :

     // class declarations
     var lastFrame:Number;
     var iterationsPerFrame:int;
    
    function startGame():void
    {
         // lets specify 3 updates per frame
         iterationsPerFrame = 3;
    
         // save initial time
         lastFrame = getTimer();
    
         // create your listener
         addEventListener(Event.ENTER_FRAME, update);
    }
    
    function update(e:Event):void
    {
         var currentFrame:Number = getTimer();
         var deltaTime:Number = (currentFrame - lastFrame)/1000;
    
         var iterationDelta:Number = deltaTime/iterationsPerFrame;
    
         for (var index:int = 0;index < iterationsPerFrame;index++)
         {
              // I'm assuming dx,dy are the velocity of the ball, in pixels per second
              ball.x += dx * iterationDelta;
              ball.y += dy * iterationDelta;
             // check collision
         }
    
    
         // set lastFrame to the currentFrame time, preparing for next frame
         lastFrame = currentFrame;
    
         // after this, your frame is going to render
    }