Коллизия Actionscript не работает - PullRequest
0 голосов
/ 11 мая 2011

Я создаю игру и столкнулся с проблемой, которую не смог выяснить. Игрок - лодка, лодка может сбрасывать мины (через пробел). Я создал массив Mine () в init ():

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

        }
    }
}

Проблема заключается в моей функции проверки столкновений. Я получаю TypeError: Ошибка № 2007: Параметр hitTestObject должен быть ненулевым. Я предполагаю, что есть проблема в том, как я создаю мины и добавляю их в массив, но я не вижу, в чем проблема.

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

        }

    }
}

1 Ответ

1 голос
/ 11 мая 2011

Просто хочу дать совет при работе с экранными объектами, которые вы также поддерживаете в отдельных массивах.

Я вижу, что: - Вы анализируете объекты (ящики или враги), используя созданные вами массивы. - Вы удаляете их из соответствующих списков отображения, но не удаляете их из массивов.

Вы должны создать механизм, который бы также удалял их из массивов, если нет цели их хранения там. Например, такая функция:

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
   [....]
}

Объединение массивов может быть не самым оптимальным решением (лучше использовать связанный список), но для небольших массивов (десятки или даже сотни) это не должно иметь значения.

И последнее: не удаляя объекты из массивов, вы сохраните ссылки на них, из-за чего сборщик мусора пропустит их

Надеюсь, это поможет.

- Михню

...