0
votes

i'm kinda new for as3 and i'm trying to make simple shooting game for my education. First, i know there are other similar questions like mine but i couldn't figure out what's wrong with mine! So if anyone can help i'll be happy a lot :)) thanks in advance

My ship moving as fixed left and right and shoots bullets when i click to big button. Also enemy ships (dusman/dusmanlar) comes down. So problem is that i couldn't figure out some bullets (mermi/mermiler) hit's and destroys some enemy ships with that very bullet itself but most of the time bullets just passing through the enemy ships and nothing happens. And of course animate gives the error Parameter hitTestObject must be non-null on this project!

What i'm doing wrong here?

var mermiler: Array = new Array(); //mermiler means bullets
var dusmanlar: Array = new Array(); // dusmanlar means enemy ships
var game_speed: int = 20;
var game_timer: int = 0;
var oyunHiz: int = 8; //bullet speed
var skor: Number = 0;

btn.addEventListener(MouseEvent.CLICK, ates);

function ates(event: MouseEvent): void {
    //whenever the mouse is pressed add the Bullet from the library to the screen
    var mermi: Mermi = new Mermi();
    mermi.x = gemi.x;
    mermi.y = gemi.y - (gemi.height / 2);
    addChild(mermi);
    //add it to the bullet array so we can loop through to move and hit test
    mermiler.push(mermi);

}

addEventListener(Event.ENTER_FRAME, basla);

function basla(event: Event): void {

    game_timer++;
    if (game_timer >= game_speed) {
        var dusman: Dusman = new Dusman();
        dusman.x = Math.random() * 640 + 10;
        dusman.y = Math.random() * 100 - 120;
        dusman.xspeed = (Math.random() * 15) - 10;
        dusman.yspeed = (Math.random() * 5) + 10;
        addChild(dusman);
        dusmanlar.push(dusman);
        game_timer = 0;
    }

    yaz.text = String(skor);
    gemi.x = mouseX;
    gemi.y = 750;

    //move all enemy ships down the screen
    for (i = 0; i < dusmanlar.length; i++) {
        //move enemy ships
        dusmanlar[i].y += dusmanlar[i].yspeed;
        dusmanlar[i].x += dusmanlar[i].xspeed;
        //bounce off sides
        if (dusmanlar[i].x >= 640 || dusmanlar[i].x <= 0) {
            dusmanlar[i].xspeed = -dusmanlar[i].xspeed;
        }
        //if reach bottom remove ship
        if (dusmanlar[i].y >= 860) {
            removeChild(dusmanlar[i]);
            dusmanlar[i] = null;
            dusmanlar.splice(i, 1);
            break;
        }
    }

    //move all the bullets on the screen up 
    for (var i: int = 0; i < mermiler.length; i++) {
        //move bullets
        mermiler[i].y -= 20;
        //if bullets got of screen
        if (mermiler[i].y <= 0) {
            removeChild(mermiler[i]);
            mermiler[i] = null;
            mermiler.splice(i, 1);
            break;
        }
    }

    //test if any bullets have hit any ships
    for (var j: int = 0; j < dusmanlar.length; j++) {
        if (mermiler != null && dusmanlar[j].hitTestObject(mermiler[i])) {
            if (mermiler.length != 0 && dusmanlar[j] != null && mermiler[i].hitTestObject(dusmanlar[j])) {
                removeChild(dusmanlar[j]);
                dusmanlar[j] = null;
                dusmanlar.splice(j, 1);

                removeChild(mermiler[i]);
                mermiler[i] = null;
                mermiler.splice(i, 1);
                skor++
                break;
            }

        }
    }
}
1

1 Answers

1
votes

There are many things you are doing in an erroneous way.

First, when you intend to browse through an Array to probably remove one or more elements from it, use backward loop rather than forward, because when you Array.splice(...) the rest of the Array shifts one position left and you miss one object. I explained the principle in this answer. You don't need to break the loop either.

// Move all enemy ships down the screen.
for (i = dusmanlar.length - 1; i >= 0; i--)
{
    // Get a ship to work with.
    var aShip:Dusman = dusmanlar[i];

    // Move the ship.
    aShip.y += aShip.yspeed;
    aShip.x += aShip.xspeed;

    if (aShip.y > 860)
    {
        // Remove the ship if it reached the bottom.
        removeChild(aShip);
        dusmanlar.splice(i, 1);
    }
    else if (aShip.x > 640)
    {
        // Bounce the ship off right.
        aShip.xspeed = -Math.abs(aShip.xspeed);
    }
    else if (aShip.x < 0)
    {
        // Bounce the ship off left.
        aShip.xspeed = Math.abs(aShip.xspeed);
    }
}

Second, you need a proper check of many objects vs many objects. The most straightforward approach is to check every possible collision.

var aShip:Dusman;
var aBullet:Mermi;

// Prepare lists for objects to remove.
var deadShips:Array = new Array;
var deadBullets:Array = new Array;

// Iterate over all enemy ships, presently alive.
for each (aShip in dusmanlar)
{
    // Iterate over all flying bullets in an inner loop.
    for each (aBullet in mermiler)
    {
        // As both ship and bullet are listed in the respective Arrays,
        // you don't need to check if they are not "null" or whatever.
        if (aShip.hitTestObject(aBullet))
        {
            // Add them for deletion. But only once.
            if (deadShips.indexOf(aShip) < 0)
            {
                deadShips.push(aShip);
            }

            // The bullets are iterated over in an inner loop,
            // you can kill many ships with the single bullet,
            // if it hits these ships at the same time.
            // Also, a single ship can take several bullets at once,
            // again, if they all hit simultaneously.
            if (deadBullets.indexOf(aBullet) < 0)
            {
                deadBullets.push(aBullet);
            }
        }
    }
}

// Now you have a list of killed ships and dead bullets.
// It's time to remove them.

var anIndex:int;

for each (aShip in deadShips)
{
    anIndex = dusmanlar.indexOf(aShip);

    // Sanity check.
    if (anIndex > 0)
    {
        dusmanlar.splice(anIndex, 1);
    }

    // Another sanity check.
    if (aShip.parent == this)
    {
        removeChild(aShip);
    }
}

for each (aBullet in deadBullets)
{
    anIndex = mermiler.indexOf(aBullet);

    // Sanity check.
    if (anIndex > 0)
    {
        mermiler.splice(anIndex, 1);
    }

    // Another sanity check.
    if (aBullet.parent == this)
    {
        removeChild(aBullet);
    }
}