0
votes

I'm making a game and ran into a problem I've been unable to figure out. The player is a boat, the boat can drop mines (via space key). I've created a Mine() Array in the 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);

}

I have a function called releaseKey() to handle keyboard events and the mines are added to the screen here:

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

        }
    }
}

The problem comes in my collision checking function. I'm getting a TypeError: Error #2007: Parameter hitTestObject must be non-null. I guess there's a problem in the way I'm creating the mines and adding them to the array but I can't see where the problem is.

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
Got it. I created 2 arrays, one for mines in inventory, and one for mines on the board. that seemed to fix things.RapsFan1981

1 Answers

1
votes

Just want to give a piece of advice for when handling display objects that you also maintain in separate arrays.

I can see that: - You're parsing the objects (crates or enemies) using the arrays made by you. - You remove them from their respective display lists, but don't remove them from the arrays.

You should make a mechanism that also remove them from the arrays unless there is a purpose for keeping them there. For example a function like:

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

And I didn't check for the parent like you did intentionally because I assume it should have a parent and if it doesn't I want to throw an error because it means there is something wrong with the rest of my code.

Also if you are parsing the array and removing elements without breaking the iteration on remove you should also decrement the iterator like this:

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

Splicing arrays might not be the most optimized solution (linked list should be the better) but for small arrays (tens, or even hundreds) it shouldn't matter.

One last thing ... not removing the objects from the arrays will keep reference of them, which will make the garbage collector skip them

Hope it helps.

-- Mihnea