操作脚本冲突不起作用



我正在制作一个游戏,遇到了一个我一直无法弄清楚的问题。玩家是一艘船,船可以投下地雷(通过空格键)。我在 init() 中创建了一个 Mine() 数组:

function initGame():void
{
    level = 1;
    player = new Player();
    //Create an enemies array
    enemies = new Array();
    //Create a plane array
    planes = new Array();
    crates = new Array();
    explosions = new Array();
    mines = new Array();
    var tempMine:MovieClip;
    for(var i:Number = 1; i < 4; i++){
        tempMine = new Mine();
        mines.push(tempMine);
        minesTxt.text = String(mines.length);
    }
    gameState = STATE_START_PLAYER;
    rightKeyIsDown = false;
    leftKeyIsDown = false;
    upKeyIsDown = false;
    downKeyIsDown = false;
    trace(gameState);
}

我有一个名为 releaseKey() 的函数来处理键盘事件,地雷被添加到这里的屏幕中:

function releaseKey(event:KeyboardEvent):void
{
    var thisKey:uint = event.keyCode;
    if (thisKey == Keyboard.RIGHT)
    {
        rightKeyIsDown = false;
    }
    if (thisKey == Keyboard.LEFT)
    {
        leftKeyIsDown = false;
    }
    if (thisKey == Keyboard.UP)
    {
        upKeyIsDown = false;
    }
    if(thisKey == Keyboard.SPACE){
        var tempMine:MovieClip;
        if(mines.length > 0){
        tempMine = new Mine();
        tempMine.y = player.y;
        tempMine.x = player.x;
        addChild(tempMine);
        mines.length--;
        minesTxt.text = String(mines.length);
        }else if(mines.length == 0){
            minesTxt.text = String(0);
        }
    }
}

问题出在我的碰撞检查功能上。我收到类型错误:错误 #2007:参数命中测试对象必须为非空。我想我创建地雷并将它们添加到数组的方式存在问题,但我看不到问题出在哪里。

function testCollisions():void
{
    var tempEnemy:MovieClip;
    var tempCrate:MovieClip;
    var tempMine:MovieClip;
    enemy:for (var i:int=enemies.length-1; i>=0; i--)
    {
        tempEnemy = enemies[i]; 
        for (var j:int=crates.length-1; j>=0; j--)
        {
            tempCrate = crates[j];
            if (tempEnemy.hitTestObject(tempCrate))
            {
                if (crates[j].parent)
                {
                    crates[j].parent.removeChild(crates[j]);
                }
                break enemy;
            }
            if (tempEnemy.hitTestObject(player))
            {
                if (player.parent)
                {
                    trace("Hit!!!!!!!!!!!!!!!!!!!!");
                    makeExplosion(player.x, player.y);
                    player.parent.removeChild(player);
                }
                break enemy;
            }
            tempMine=mines[i];
            if (tempEnemy.hitTestObject(tempMine))
            {
                if (tempEnemy.parent)
                {
                    trace("BOOM!!!!!!!!!!!!!!!!!!!!");
                    makeExplosion(tempEnemy.x, tempEnemy.y);
                    player.parent.removeChild(tempEnemy);
                }
                break enemy;
            }
            if (player.hitTestObject(tempCrate))
            {
                if (crates[j].parent)
                {
                    crates[j].parent.removeChild(crates[j]);
                }
            }
        }
    }
}

只是想在处理也在单独数组中维护的显示对象时给出一条建议。

我可以看到:- 你正在使用你制作的数组来解析对象(板条箱或敌人)。- 将它们从各自的显示列表中删除,但不从数组中删除它们。

您应该建立一种机制,也将它们从数组中删除,除非有将它们保留在那里的目的。例如,像这样的函数:

function RemoveCrate(index) : void
{
   crates[index].parent.removeChild(crates[index]); /// remove from display list
   crates.splice(index, 1); /// remove reference from the array;
}

而且我没有像你故意那样检查父级,因为我认为它应该有一个父级,如果没有,我想抛出一个错误,因为这意味着我的其余代码有问题。

此外,如果您正在解析数组并删除元素而不破坏删除迭代,您还应该像这样减少迭代器:

for(var i:int = 0; i < crates.length; i++)
{
   [....]
   RemoveCrate(i);
   i --;  // not doing this after deletion will skip one element in the next iteration
   [....]
}

拼接数组可能不是最优化的解决方案(链表应该更好),但对于小数组(数十个,甚至数百个)来说,这无关紧要。

最后一件事...不从数组中删除对象将保留对它们的引用,这将使垃圾回收器跳过它们

希望对您有所帮助。

--米赫内亚

最新更新