as3 #1009 error code provided. “Null Object refere

2020-02-15 08:31发布

hi I'm relatively new to as3 (this year) and I'm getting this error

typer error #1009 cannot access a property or method of a null object reference. at FoodObject/collisionTest()

i was hoping anyone could help

package {
import flash.events.MouseEvent;
import flash.events.KeyboardEvent;
import flash.events.*
    import flash.utils.*
    import flash.display.Stage;

public class GameScene1 extends Scene {

    //public variables
    //character & scenery
    public var mainChar: Character;
    public var testFood: FoodObject;




    //constructor is used to create all necessary objects for this scene and display them
    public function GameScene1(gm_: Manager) {

        //constructor

        super(gm_);
        trace("GameScene 1 constructor");


        //character
        mainChar = new Character;
        addChild(mainChar);
        mainChar.x = 200;
        mainChar.y = 200;


        testFood = new FoodObject;
        addChild(testFood)
        testFood.x = 50
        testFood.y = 200

the food object class is here.

package  {
import GameScene1
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.TimerEvent;


public class FoodObject extends MovieClip {
    public var Game1:GameScene1;

    public function FoodObject() {
         //constructor code
        this.addEventListener(Event.ENTER_FRAME, collisionTest)
    }

    public function collisionTest(e:Event)
    {
        if (this.hitTestObject(Game1.mainChar))
        {
            trace("it works")
        }
    }

}

}

game manager here: package {

import flash.display.MovieClip;


public class Manager extends MovieClip {

    //stores which scene is currently loaded
    public var curScene:Scene=null;

    public function Manager() {
        //constructor
        trace("Manager Construct")
        GoToScene("menu");
    }


    public function GoToScene(name:String)
    {
        if (curScene) //there was a scene already
        {
        curScene.OnLeaveScene(); //call its OnLeaveScene function to remove all objects
        removeChild(curScene);
        }

        if(name=="menu") curScene = new MenuScene(this);
        if(name=="select") curScene = new SelectScene(this);
        if(name=="game1") curScene = new GameScene1(this);
        if(name=="game2") curScene = new GameScene2(this);
        if(name=="game3") curScene = new GameScene3(this);
        if(name=="credit") curScene = new CreditScene(this);

        addChild(curScene);
    }


}

2条回答
▲ chillily
2楼-- · 2020-02-15 09:00

Your problem is that the concerns of your classes are not separate:

Your Scene knows both the Character and the Food object, you instantiate both classes there, nothing wrong with that.

The problem starts when you are trying to do something in the Food object, that requires knowledge of the character. The thing is: the Food object doesn't know anything about the Character.

You can solve this by simply passing the reference of Character to your Food object. In order to do this, modify the constructor like so:

private var character:Character;
public function FoodObject(character:Character) {
     //constructor code
    this.addEventListener(Event.ENTER_FRAME, collisionTest)
    this.character = character;
}

The usage of said constructor in your Scene changes as follows:

testFood = new FoodObject(mainCharacter);

This way, Food knows the character and can do stuff with it, for example do collision tests:

   public function collisionTest(e:Event)
    {
        if (this.hitTestObject(character)) // ==== this line changed
        {
            trace("it works")
        }
    }

However, this raises an important issue: Why should Food know the Character at all?

Sure enough, you want to do the collision test, which requires both objects. But why do you want to do it in the Food object?

Doing the collision check in Food is cumbersome, because you have to pass a reference to Character in order to do it there.

The much preferred way of doing this is to do the collision check where both objects participating in the check are already known. In your case, this is the Scene.

Think about how easy it is to do the check in Scene:

testFood.hitTestObject(mainCharacter);

It's that simple, because everything you need is already there.


To recap:

  • The collision check requires knowledge of 2 objects that you want to check.
  • In order to do the check in either one, you have to pass a reference of the other. (Character to Food as seen above or the other way round)
  • It is a lot easier to do the check in some place that already knows both objects, because no reference have to be passed around.

Your original code failed because Game1 in FoodObject is never assigned a value and therefore remains null. Invoking methods on null causes the error you experienced.

查看更多
劳资没心,怎么记你
3楼-- · 2020-02-15 09:10

You forgot to take the instance of GameScene1 class using new keyword.

public var Game1:GameScene1;

public function FoodObject() {
     //constructor code
     var _manager:Manager = new Manager();
     Game1 = new GameScene1(_manager)
    this.addEventListener(Event.ENTER_FRAME, collisionTest);
}

public function collisionTest(e:Event):void{
    ....
}
查看更多
登录 后发表回答