Actionscript 3 突破式保险箱系统

Actionscript 3 突破式保险箱系统,actionscript-3,breakout,Actionscript 3,Breakout,我已经为此工作了几个星期了,我可以让它正常工作。就快到了,我想我错过了什么。我基本上不能让方块和球之间的碰撞检测像我让它们工作一样工作 球仍有机会在几秒钟内铲出大量的挡块。我很想听听有类似问题的人的意见 这是代码 private function checkCollision():void { grdx = Math.floor((ball.x) / 28); grdy = Math.floor((ball.y) / 14); ngrdx

我已经为此工作了几个星期了,我可以让它正常工作。就快到了,我想我错过了什么。我基本上不能让方块和球之间的碰撞检测像我让它们工作一样工作

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

这是代码

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

            }
        }

    }
私有函数checkCollision():void
{
grdx=数学楼层((ball.x)/28);
grdy=数学地板((球y)/14);
ngrdx=数学地板((ball.x+dx)/28);
ngrdy=数学地板((球y+dy)/14);
如果(grdy=0)
{   
如果(级别[grdy][ngrdx]>0)
{
级别[grdy][ngrdx]=0;
bnm=“Block_”+grdy+“”+ngrdx;
if(this.getChildByName(bnm)!=null)
{
this.removeChild(this.getChildByName(bnm));
dx*=-1;
totalBreaks++;
跟踪(“击中X”);
跟踪(“块:“+totalBreaks+”/“+totalBlocks”);
}
}
如果(级别[ngrdy][grdx]>0,则为else)
{               
bnm=“Block”+ngrdy+“+grdx;
级别[ngrdy][grdx]=0;
if(this.getChildByName(bnm)!=null)
{
this.removeChild(this.getChildByName(bnm));
dy*=-1;
totalBreaks++;
跟踪(“击中Y”);
跟踪(“块:“+totalBreaks+”/“+totalBlocks”);
}
}
如果(级别[ngrdy][ngrdx]>0)
{               
bnm=“Block_”+ngrdy+“”+ngrdx;
级别[ngrdy][ngrdx]=0;
if(this.getChildByName(bnm)!=null)
{
this.removeChild(this.getChildByName(bnm));
dy*=-1;
dx*=-1;
totalBreaks++;
跟踪(“击中X,Y”);
跟踪(“块:“+totalBreaks+”/“+totalBlocks”);
}
}
}
}

我不确定我是否正确,但我认为一个问题可能是您的
if-else-if
语句

从您的示例中,调用
checkCollision()
可能会更改两次
dx
dy
变量,导致球在击中砖块时继续朝同一方向移动

如果我是对的,那么您可以重构
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=0)
我将写下:

if ((grdy <= level.length - 1) && (ngrdy <= level.length - 1) && (grdy >= 0) && (ngrdy >= 0))
if((grdy=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++;
    }
}
私有函数checkCollision():void
{
grdx=数学楼层((ball.x)/28);
grdy=数学地板((球y)/14);
ngrdx=数学地板((ball.x+dx)/28);
ngrdy=数学地板((球y+dy)/14);
var flipX:Boolean=false;
变量flipY:Boolean=false;
如果((grdy=0))
{
if(测试块(grdx、ngrdy))
{
flipY=true;
}
if(测试块(ngrdx、grdy))
{
flipX=真;
}
if(测试块(ngrdx、ngrdy))
{
flipX=真;
flipY=true;
}
dx*=flipX?-1:1;
dy*=弗利比?-1:1;
}
}
私有函数测试块(xPos:int,yPos:int):布尔值
{
如果(级别[YPO][xPos]>0)
{
跟踪(“击中X,Y”);
级别[YPO][XPO]=0;
断块(“断块+yPos+”+xPos);
跟踪(“块:“+totalBreaks+”/“+totalBlocks”);
返回true;
}
返回false;
}
私有函数breakBlock(blockName:String):void
{
if(this.getChildByName(blockName))
{
this.removeChild(this.getChildByName(blockName));
totalBreaks++;
}
}

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

按照您的建议在If语句中更改,使游戏正常运行!你的链接似乎被破坏了-
“错误-不存在这样的转储。”
虽然我想看看我的第一个建议对游戏有什么影响,但我编辑了我的答案,添加了第二个解决方案。上传时遇到了一些问题,但它基本上使球总是在两个轴上翻转,所以每次击中它都会回到原来的方式。我会尽快给你的第二个解决方案,看看会发生什么。