突破hitbox系统



我已经为此工作了几个星期了,现在我可以让它工作了。就快到了,我想我还缺了点什么。我基本上不能让方块和球之间的碰撞检测像我想要的那样工作。

转储SWF

球仍然有机会在几秒钟内犁出大量的方块。我很想听听有类似问题的人的意见。

下面是代码;

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);
                }
            }
        }
    }

我不确定我是对的,但我认为一个问题可能与你的if else if语句有关。

从你的例子中,对checkCollision()的调用可能会改变两次你的dxdy变量,导致球在击中砖块时保持相同的方向。

如果我是对的,那么你可以像下面这样重构你的if语句:

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

此外,将简单的测试括在括号中是一个很好的实践。所以我们不写

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

我会这样写:

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

使代码更易读。

干得好,继续干!

编辑:正如你的评论表明这不是一个正确的答案,我挖掘了一点,我现在有另一个建议,使用一些布尔值来检查方向是否应该在两个轴上翻转。我还做了一些重构:

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++;
    }
}

如果它恰好是正确的解决方案,我会清理这个答案…

相关内容

  • 没有找到相关文章

最新更新