-1

I'm just learning how to use classes in AS3 using some very basic code and I'm tearing my hair out trying to figure out how to do the simplest thing.

I've made the document class the 'Test' class (essentially my main class), and all I'm trying to do with it is add an instance of the 'WhiteBall' class (a movieclip) to the stage.

The 'WhiteBall' class is supposed to allow me to control the movieclip with the keyboard. I don't know if this part works yet, because I keep getting this error:

TypeError: Error #1009: Cannot access a property or method of a null object reference. at WhiteBall$iinit()[/Users/Owner/Desktop/Animation/Coding/WhiteBall.as:13] at Test$iinit()[/Users/Owner/Desktop/Animation/Coding/Test.as:11]

Here is the code for the 'Test' class:

package {
    import flash.display.MovieClip;
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.ui.Keyboard;



    public class Test extends MovieClip
    {
        var whiteBall:WhiteBall = new WhiteBall ();

        public function Test() {

            addEventListener(Event.ENTER_FRAME, whiteBallSpawn);

        }

        public function whiteBallSpawn(evt:Event) {


            stage.addChild(whiteBall);
            whiteBall.x = 200;
            whiteBall.y = 250;




        }





    }
}

Here is the code for the 'WhiteBall' class:

package {
    import flash.display.MovieClip;
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.ui.Keyboard;

    public class WhiteBall extends MovieClip
    {


        public function WhiteBall() {

            stage.addEventListener(KeyboardEvent.KEY_DOWN, keysdown);
        }

        public function keysdown(mykey:KeyboardEvent) {

        if(mykey.keyCode==Keyboard.UP) {
            this.y--;
        }

        if(mykey.keyCode==Keyboard.DOWN) {
            this.y++;
        }

        if(mykey.keyCode==Keyboard.RIGHT) {
            this.x++;
        }

        if(mykey.keyCode==Keyboard.LEFT) {
            this.x--;
        }
    }
    }
}

The line-11 error in the 'Test' class refers to this line:

var whiteBall:WhiteBall = new WhiteBall ();

I have no idea what the problem is here. Any help you could give me would be really appreciated.

Brojack
  • 3
  • 2
  • Easy. You try to access **stage** in the WhiteBall constructor. However, this instance does not belong to display list, thus its **stage** field is **null**. You need first **addChild(whiteBall);** in the main class, and only then try to access the **stage** from the ball itself (which means you should write some kind of **initBall()** method and call it after you have added the instance to display list). – Organis Oct 19 '17 at 20:38
  • Oh, I see. I'll give it a go next time I sit down to code and see if I can get it to work. Thanks so much for the help and the clear explanation! – Brojack Oct 19 '17 at 22:45
  • Try as `new WhiteBall();` instead of the current `new WhiteBall ();` – VC.One Oct 20 '17 at 06:49
  • Thanks for the suggestions, guys. To VC.One - changing the 'new WhiteBall ();' to 'new WhiteBall();' as you suggested didn't seem to fix the issue. The error message remained the same and referred to the same lines. To Organis - I've tried to implement the method the way you've described, but since I'm such a total noob I can't figure out how to do it. Could you specifically show me with some code how you would implement this (i.e. what are the conditionals for the initBall() method)? Only if you have the time. – Brojack Oct 21 '17 at 09:06
  • Possible duplicate of [AS3 -TypeError #1009 - any easy way to find out \*which\* object reference is null?](https://stackoverflow.com/questions/1518118/as3-typeerror-1009-any-easy-way-to-find-out-which-object-reference-is-null) – Brian Oct 23 '17 at 19:53

1 Answers1

0

What Organis said is this: When you create a DisplayObject, for example a MovieClip which is the class that your WhiteBall extends, then the stage property of that object is null. That means that when you tried to access the stage property of your whiteball on its constructor

public function WhiteBall() 
{
   stage.addEventListener(KeyboardEvent.KEY_DOWN, keysdown);
} 

an error was thrown because stage was null. So to solve this the safest and most common way is to wait until the ball is added to stage and then listen for any stage keyboard events. Like so:

public function WhiteBall() 
{
    if(stage != null)
    {
        stage.addEventListener(KeyboardEvent.KEY_DOWN, keysdown);
    }
    else
    {
       this.addEventListener(Event.ADDED_TO_STAGE, addedToStage);
    }
}
private function addedToStage(e:Event):void
{
   this.removeEventListener(Event.ADDED_TO_STAGE, addedToStage);
   stage.addEventListener(KeyboardEvent.KEY_DOWN, keysdown);
}

So the moment your Test class instance will add the ball to the stage, then the stage property of your WhiteBall instance will have a value and therefore it will be safe to listen for any keyboard events.

xerx
  • 119
  • 1
  • 6