Removing an Object when it hits another object AS3

2019-08-08 19:24发布

问题:

Beginner here. I have a symbol on the timeline with an instance name of 'island', so basically I want to remove the cells that hits the 'island'

if (cell.hitTestObject (island)) {

             if(stage.contains(cell))
             removeChild (cell);
         }

I tried this one under the moveCell function but it only removes one cell instead of every cell that hits the island. Thanks everyone!

Here's my code so far:

 package  {
    import flash.display.MovieClip;
    import flash.utils.Timer;
    import flash.events.TimerEvent;

    public class Main extends MovieClip {

        public var cell:Cell;
        public var group:Array;
        public var gameTimer:Timer;


        public function Main() {

            cell = new Cell (400, -15);
            addChild (cell);

            group = new Array();
            var newCell = new Cell (100, -15);
            group.push ( newCell);
            addChild(newCell);


            gameTimer = new Timer (25);
            gameTimer.addEventListener(TimerEvent.TIMER,moveCell);
            gameTimer.start();
        }

        public function moveCell (timerEvent:TimerEvent):void {

             if (Math.random() < 0.01) {
             var randomX:Number = Math.random() * 700;
             var newCell:Cell = new Cell (randomX, -15);
             group.push (newCell);
             addChild(newCell);
             }


         for each(var i:MovieClip in group) {
             if (i.hitTestObject(island)) {

                i.visible = false;
                //i.parent.removeChild(i); 

                var score:int = 0;

                 score ++;

                scoreOutPut.text = score.toString();



             }   
         }



        }

    }

}`

回答1:

You got the "Cannot access a property or method of a null object reference" because you've removed the Cell object from the DisplayObjectContainer (its parent) but not from the group array, so in the next iteration of your for loop, that object didn't exist anymore and that error will be fired.

To avoid that you can do like this :

for(var i:int = 0; i < group.length; i++)
{               
    var cell:Cell = Cell(group[i]);
    if (cell.hitTestObject(island))
    {
        cell.parent.removeChild(cell);
        group.splice(i, 1);     
        score++;
    }
}

For the score, it should be a global property for all your class to get updated every time.

Also, for your code to be more organised and clearer, it's better to put every task in a single method.

For example, for creating cells, you can use a createCell() method :

// 0 is the default value of __x and -15 is the default one of __y
private function createCell(__x:Number = 0, __y:Number = -15): void 
{
    var cell:Cell = new Cell(__x, __y);
    group.push(cell);
    addChild(cell);
}

Then you can use it in any place in your code, for example, for your two first cells that you create in the constructor :

public function Main()
{
    // ..

    createCell(400);
    createCell(100);

    // ...
}

Or inside the moveCell() method :

if (Math.random() < 0.01)
{
    var randomX:Number = Math.random() * 700;
    createCell(randomX);
}

Also, if you don't really need that a property or a method to be public, don't put it as public.

...

Hope that can help.