#1009: Cannot access a property or method of a null object reference. with random dropping squares

StackOverflow https://stackoverflow.com/questions/21646664

سؤال

i am rebuilding a top down shooter form a .fla files with actions in it to a separate .as file managed to fix allot of problems with is but i stumbled upon a problem with a function that drops random squares in to a particleContainer and adds them to stage to float down.

when the page is loaded is get allot of

TypeError: Error #1009: Cannot access a property or method of a null object reference. at Level/generateParticles()

i really hope someone can help me fix this! and show me where i made a mistake, i have tried allot of things already but none of them seem to work:(

    package {
import playerAuto
import flash.display.Sprite;
import flash.display.MovieClip;
import flash.display.Stage;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.filters.BlurFilter;
import flash.utils.Timer;
import flash.text.TextField;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.media.SoundMixer;
import flash.utils.*;
import flash.display.Shape;
import flash.display.DisplayObject

/** 
 * 
 */
public class Level extends Sprite
{

    //these booleans will check which keys are down
    public var leftIsPressed:Boolean = false;
    public var rightIsPressed:Boolean = false;
    public var upIsPressed:Boolean = false;
    public var downIsPressed:Boolean = false;
    //how fast the character will be able to go
    public var speed:Number = 5;
    public var vx:Number = 0;
    public var vy:Number = 0;
    //how much time before allowed to shoot again
    public var cTime:int = 0;
    //the time it has to reach in order to be allowed to shoot (in frames)
    public var cLimit:int = 12;
    //whether or not the user is allowed to shoot
    public var shootAllow:Boolean = true;
    //how much time before another enemy is made
    public var enemyTime:int = 0;
    //how much time needed to make an enemy
    //it should be more than the shooting rate
    //or else killing all of the enemies would
    //be impossible :O
    public var enemyLimit:int = 16;
    //the PlayerAuto's score
    public var score:int = 0;
    //this movieclip will hold all of the bullets
    public var bulletContainer:MovieClip = new MovieClip();
    //whether or not the game is over
    public var gameOver:Boolean = false;


    private var PlayerAuto:playerAuto = new playerAuto;

    // publiek toegangkelijke verwijzing naar deze class
    public static var instance:Level;

    public var particleContainer:MovieClip = new MovieClip();

    // constructor code
    public function Level()
    {
        instance = this;
        PlayerAuto.x = 200;
        PlayerAuto.y = 100;
        addChild(this.PlayerAuto);
        Project.instance.stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
        Project.instance.stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
        Project.instance.stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
        Project.instance.stage.addEventListener(Event.ENTER_FRAME, generateParticles);
        drieButton.addEventListener( MouseEvent.CLICK, loadScreenThree );

        //checking if there already is another particlecontainer there
        if(particleContainer == null)
        {
            //this movieclip will hold all of the particles
            addChild(this.particleContainer);
        }
    }

    function keyDownHandler(e:KeyboardEvent):void {
        switch(e.keyCode) {
            case Keyboard.LEFT : leftIsPressed = true; break;
            case Keyboard.RIGHT : rightIsPressed = true; break;
            case Keyboard.UP : upIsPressed = true; break;
            case Keyboard.DOWN : downIsPressed = true; break;
        }
    }

    function keyUpHandler(e:KeyboardEvent):void {
        switch(e.keyCode) {
            case Keyboard.LEFT : leftIsPressed = false; break;
            case Keyboard.RIGHT : rightIsPressed = false; break;
            case Keyboard.UP : upIsPressed = false; break;
            case Keyboard.DOWN : downIsPressed = false; break;
        }
    }

    function enterFrameHandler(e:Event):void {
        vx = -int(leftIsPressed)*speed + int(rightIsPressed)*speed;
        vy = -int(upIsPressed)*speed + int(downIsPressed)*speed;
        PlayerAuto.x += vx;
        PlayerAuto.y += vy;
    }

    function generateParticles(event:Event):void
    {
        //so we don't do it every frame, we'll do it randomly
        if(Math.random()*10 < 2){
            //creating a new shape
            var mcParticle:Shape = new Shape(); 
            //making random dimensions (only ranges from 1-5 px)
            var dimensions:int = int(Math.random()*5)+1;
            //add color to the shape
            mcParticle.graphics.beginFill(0x999999/*The color for shape*/,1/*The alpha for the shape*/);
            //turning the shape into a square
            mcParticle.graphics.drawRect(dimensions,dimensions,dimensions,dimensions);
            //change the coordinates of the particle
            mcParticle.x = int(Math.random()*stage.stageWidth);
            mcParticle.y = -10;
            //adding the particle to stage
            particleContainer.stage.addChild(mcParticle);
        }

        //making all of the particles move down stage
        for(var i:int=0;i<particleContainer.numChildren;i++){
            //getting a certain particle
            var theParticle:DisplayObject = particleContainer.getChildAt(i);
            //it'll go half the speed of the character
            theParticle.y += speed*.5;
            //checking if the particle is offstage
            if(theParticle.y >= 400){
                //remove it
                particleContainer.stage.removeChild(theParticle);
            }
        }
    }


    /**
     * eventhandler voor als je op de tweede knop klikt
     */
    private function loadScreenThree( event:MouseEvent ):void
    {
        // eerst opruimen!
        cleanListeners();

        // dan naar ander scherm
        Project.instance.switchScreen( "derde" );
    }

    private function cleanListeners():void
    {
        drieButton.removeEventListener( MouseEvent.CLICK, loadScreenThree );
        stage.removeEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
        stage.removeEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
        stage.removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
        stage.removeEventListener(Event.ENTER_FRAME, generateParticles);
    }

}
}
هل كانت مفيدة؟

المحلول

I think the problem is here:

    for(var i:int=0;i<particleContainer.numChildren;i++){
        var theParticle:DisplayObject = particleContainer.getChildAt(i);
        [...]
        if (theParticle.y >= 400){
            particleContainer.removeChild(theParticle);
        }
    }

You are removing children from the particleContainer while iterating through it. This is usually a bad idea because once you remove an item from the beginning, you are changing the index of all following items.

One solution is to loop backwards, so when you remove something the only items changed are the ones that you already checked.

    for(var i:int=particleContainer.numChildren - 1; i>=0; i--){

And the rest keeps the same.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top