0

I've been working on this for several weeks now and I can get it to work as It to work. It's almost there I guess there is just something I'm missing. I basically cant get the collision detection betwen the blocks and the ball to work like I wnat them to work.

Dump SWF

The ball still has a chance to plow loads of block within seconds. I would love to hear form people who have had a similiar problem.

Here's the 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);


        if (grdy <= level.length - 1 && ngrdy <= level.length - 1 && grdy >= 0 && ngrdy >= 0) 
        {   

            if(level[grdy][ngrdx] > 0) 
            {

                level[grdy][ngrdx] = 0;
                bnm = "Block_" + grdy + "_" + ngrdx;    
                if (this.getChildByName(bnm) != null)
                {

                    this.removeChild(this.getChildByName(bnm));
                    dx *= -1;   
                    totalBreaks++;

                    trace("Hit on X");
                    trace("Block: " + totalBreaks + " / " +  totalBlocks);
                }


            }
            else if(level[ngrdy][grdx] > 0) 
            {               

                bnm = "Block_" + ngrdy + "_" + grdx;
                level[ngrdy][grdx] = 0; 
                 if (this.getChildByName(bnm) != null)
                {

                    this.removeChild(this.getChildByName(bnm));
                    dy *= -1;
                    totalBreaks++;
                    trace("Hit on Y");
                    trace("Block: " + totalBreaks + " / " +  totalBlocks);
                }
            }
            if(level[ngrdy][ngrdx] > 0) 
            {               

                bnm = "Block_" + ngrdy + "_" + ngrdx;
                level[ngrdy][ngrdx] = 0;    
                if (this.getChildByName(bnm) != null)
                {

                    this.removeChild(this.getChildByName(bnm));
                    dy *= -1;
                    dx *= -1;
                    totalBreaks++;
                    trace("hit on X,Y");
                    trace("Block: " + totalBreaks + " / " +  totalBlocks);
                }

            }
        }

    }

1 Answers1

0

I'm not sure I got this right but I think one problem can be with your if else if statements.

From your example, a call to checkCollision() might change twice your dx and dy vars, resulting in the ball keep going in the same direction while it hit a brick.

If I'm right then you may refactor your if statements like the following:

if (level[ngrdy][ngrdx] > 0)
{
    [...]
}
else if (level[grdy][ngrdx] > 0)
{
    [...]
}
else if (level[ngrdy][grdx] > 0)
{
    [...]
}

Besides, it's a good practice to enclose simple tests into parenthesis. So instead of writing that:

if (grdy <= level.length - 1 && ngrdy <= level.length - 1 && grdy >= 0 && ngrdy >= 0)

I would write this :

if ((grdy <= level.length - 1) && (ngrdy <= level.length - 1) && (grdy >= 0) && (ngrdy >= 0))

thus making the code more readable.

Good work though, keep going on!

EDIT: As your comment suggest it is not a correct answer, I dig a bit more and I now have another suggestion, using some booleans to check whether the direction should be flipped on both axes. I also did a bit of refactoring:

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;
        }
        if (testBlock(ngrdx, grdy))
        {
            flipX = true;
        }
        if (testBlock(ngrdx, ngrdy))
        {
            flipX = true;
            flipY = true;
        }

        dx *= flipX ? -1 : 1;
        dy *= flipY ? -1 : 1;
    }
}

private function testBlock(xPos:int, yPos:int):Boolean
{
    if (level[yPos][xPos] > 0)
    {
        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++;
    }
}

If it happened to be the correct solution, I'd clean this answer...

duTr
  • 714
  • 5
  • 21
  • changin the if statements as you suggested makes the game do [this](http://www.newgrounds.com/dump/item/97e02b7ef9a1dc7cfd91153a06bc204a)! – Drexl Spivey Mar 19 '13 at 04:09
  • You link seems to be broken - `"ERROR — No such dump exists."` – duTr Mar 19 '13 at 08:28
  • Although I'd like to see what my first suggestion makes to the game, I edited my answer to add a second solution – duTr Mar 19 '13 at 09:05
  • Had some trouble uploading but it basically made the ball always flip in both axes, so on every hit it would come back the way it came. Gonna give your second soloution a go as quick as I can and see what happens. – Drexl Spivey Mar 19 '13 at 15:11