actionscript-3adobeflashdevelop

How to spawn objects in array without repeating?


I have MC's rockThrowers that are added to the stage in 3 different positions. They spawn randomly using a random generator which is working fine. The user clicks a button on the stage and the rockThrowers are added to the stage and pushed in their own array aRockThrowerArray I want to be able to check which of 3 positions they spawned on and not overlap the next rockThrowers that are added to the stage and if so then add a new one to the empty positions. I have tried different strategies mainly booleans and calling them from their own class to my main class but nothing seems to work. Here is my

rockThrowers Class:

    private function startPosition():void 
    {
        // y position 
        this.y =  (stage.stageHeight / 2) + 200;

        //Start Speed
        nSpeed = randomNumber(5, 8);

        leftScreenSpawn = randomNumber(1, 3);


        //For Left Screen
        leftNeg =  (stage.stageWidth / 2) - 200;
        leftMiddle =  (stage.stageWidth / 2) - 150;
        leftPos =  (stage.stageWidth / 2) - 100;



        //Left Screen
        if (leftScreenSpawn == 1)
        {
            this.x = leftNeg;
            bLeftNeg = true; // Now if the left Rock thrower is destroyed then turn back to false on main engine class
        }else
        if (leftScreenSpawn == 2)
        {
            this.x = leftMiddle;
            bLeftMiddle = true;
        }else
        if (leftScreenSpawn == 3)
        {
            this.x = leftPos;
            bLeftPos = true;
        }



        //Move 
        startMoving();
    }

Now in my Main Class I have it setup like so for when the user clicks the left screen Btn:

    private function rockThrowerSpawn(e:MouseEvent):void 
    {
        //Instantiate screens before hand
        rockThrowerSpawnScreen.x = (stage.stageWidth / 2);
        rockThrowerSpawnScreen.y = (stage.stageHeight / 2) + 200;
        addChild(rockThrowerSpawnScreen);

        rockThrowerSpawnScreen.left.addEventListener(MouseEvent.CLICK, chooseSpawnSideRockThrowers);

    }

Then the Spawn Function:

private function chooseSpawnSideRockThrowers(e:MouseEvent):void 
    {
        if (e.currentTarget == rockThrowerSpawnScreen.left) // Spawn LEFT
        {

            //add new rock thrower
             rockThrowers = new mcRockThrowers();
             //Add object
             addChild(rockThrowers);
             //Add to Array
             aRockThrowerArray.push(rockThrowers);
             //trace("LEFT SPAWN");

        }

        //Subtract resources and update text
        nResources -= 10;
        updateResourceTextField();


        //Remove Listeners
        rockThrowerSpawnScreen.left.removeEventListener(MouseEvent.CLICK, chooseSpawnSideRockThrowers);
        rockThrowerSpawnScreen.destroy();
    }

I understand that this alone will always spawn random positions I deleted everything that wasn't working now I'm back to this square one. Any ideas on how I can accomplish this? All support is appreciate.


Solution

  • Easy. You need a finite Array that produces 3 values in a random order.

    var L:Array =
    [
        (stage.stageWidth / 2) - 200,
        (stage.stageWidth / 2) - 150,
        (stage.stageWidth / 2) - 100,
    ];
    
    function fetchPosition():Number
    {
        // Get a random index based on the current length of L.
        var anIndex:int = Math.random() * L.length;
    
        // Record the result.
        var result:Number = L[anIndex];
    
        // Remove the result from the list.
        L.splice(anIndex, 1);
    
        return result;
    }
    

    So, you can validly call fetchPosition() three times per application run, and each run the contents of L will be fetched in random order and, more importantly, you won't get the same value twice, because the fetched value is removed from the data set.