How can I solve my hitTestObject Collision Null Ob

2019-08-10 03:29发布

问题:

I've been trying for days now to add a simple hitTest between my player class and some "buildings" without success. I've tried adding the hitTest to the player class & when didn't work, the building class. I've tried variations of the code on both also with no luck. I've been reading tutorials for days & no matter what I try, nothing seems to work - so, I must be doing something so simply wrong that the common sense just eludes me.

I have three classes that could/should be affected by the hitTest: the player class, building class, &/or objectPlacer class. For this question I have left player class untouched, thinking that later I will add a Boolean to it's movement based on the hitTest from the building class. The ObjectPlacer class is instantiated at start. It's function is to instantiate buildings, flora, fauna, etc...I' m leaving it untouched as well thinking, that the "building" class is where I want the hitTest to be applied.

Here is my building code:

package com.gamecherry.gunslinger
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.display.Stage;

public class  BuildingsLeft03 extends MovieClip
{
    private var speed:Number = 1;
    private var startX:Number;
    private var startY:Number;
    private var stageRef:Stage;
    private var target:Cowboy;

    public function BuildingsLeft03(stageRef:Stage, startX:Number,   startY:Number, target:Cowboy)
    {
        this.stageRef = stageRef;
        this.target = target;
        x = startX;
        y = startY;

        addEventListener(Event.ENTER_FRAME, loop, false, 0, true);

    }       

        public function loop(e:Event) : void
    {
        y+= speed;
        if (y > 544)
        removeSelf();

        if (hitTestObject(target.hit))
        {
            trace("hitTestObject");
        }
    }






    private function removeSelf() : void
    {
      removeEventListener(Event.ENTER_FRAME, loop);

      if (stageRef.contains(this))
      stageRef.removeChild(this);
    }       
}

}

This all results in the following output error: TypeError: Error #1009: Cannot access a property or method of a null object reference. at com.gamecherry.gunslinger::BuildingsLeft03/loop()

What exactly am I doing wrong? I've tried everything I can think of (I'm new to coding) & if I'm not getting this error then I'm getting some other error.

I wanted to be respectful of the help I'm asking for by not posting all my code (it's nice enough for you all to try & help without having to read through three pages of my admittedly amateur code) but, perhaps shining more light on my ineptitude will help in narrowing down the problem.

Here is my player class code:

  package com.gamecherry.gunslinger
{
import flash.display.MovieClip;
import flash.display.Stage;
import com.senocular.utils.KeyObject;
import flash.ui.Keyboard;
import flash.events.Event;
import flash.utils.Timer;
import flash.events.TimerEvent;

public class  Cowboy extends MovieClip
{
    private var stageRef:Stage;
    private var key:KeyObject;
    private var speed:Number = 0.5;
    private var vx:Number = 0;
    private var vy:Number = 0;
    private var friction:Number = 0.93;
    private var maxSpeed:Number = 2;
    private var fireTimer:Timer;
    private var canFire:Boolean = true;



    public function Cowboy(stageRef:Stage)
    {

        this.stageRef = stageRef;
        key = new KeyObject(stageRef);

        fireTimer = new Timer(300, 1);
        fireTimer.addEventListener(TimerEvent.TIMER, fireTimerHandler, false, 0, true);

        addEventListener(Event.ENTER_FRAME, loop, false, 0, true);

    }

    public function loop(e:Event) : void
    {
        if (key.isDown(Keyboard.SPACE))
        fireBullet();

        if (key.isDown(Keyboard.LEFT))
        vx -= speed;
        else if (key.isDown(Keyboard.RIGHT))
        vx += speed;
        else
        vx *= friction;

        if (key.isDown(Keyboard.UP))
        vy -= speed;
        else if (key.isDown(Keyboard.DOWN))
        vy += speed;
        else 
        vy *= friction;


        if (key.isDown(Keyboard.SPACE) && key.isDown(Keyboard.LEFT))
        fireBullet();


        x += vx;
        y += vy;


        //rotation = vx * 12;

        if (vx > maxSpeed)
        vx = maxSpeed;
        else if (vx < -maxSpeed)
        vx = -maxSpeed;

        if (vy > maxSpeed)
        vy = maxSpeed;
        else if (vy < -maxSpeed)
        vy = -maxSpeed;

        //scaleX = (maxSpeed - Math.abs(vx)) / (maxSpeed * 4) + 0.75;

        //If Cowboy touches edge of screen - he bounces back
        if (x > stageRef.stageWidth)
        {
            x = stageRef.stageWidth;
            vx = -vx;
        }
        else if (x < 0)
        {
        x = 0;
        vx = -vx
        }

        if (y > stageRef.stageHeight)
        {
        x = stageRef.stageHeight;
        vy = -vy;
        }
        else if (y < 0)
        {
            y = 0;
            vy = -vy
        }


    }

    private function fireBullet() : void
    {
        if (canFire)
     {

        stageRef.addChild(new PlayerBullet(stageRef, x - 10 + vx, y - 10, vx, vy));
        canFire = false;
        fireTimer.start();
     }

    }

    private function fireTimerHandler(e: TimerEvent) : void
    {
        canFire = true;
    }

}

}

Here is my ObjectPlacer code:

   package com.gamecherry.gunslinger
{
import flash.display.MovieClip;
import flash.display.Stage;
import flash.events.Event;
import flash.utils.Timer;
import flash.events.TimerEvent;

public class  ObjectPlacer extends MovieClip
{

    private var Build01Timer:Timer;
    private var Build02Timer:Timer;
    private var CactiSet01Timer:Timer;

    private var build01Place:Boolean = false;// if true - addChild starts at first frame
    private var build02Place:Boolean = false;
    private var cactiSet01Place:Boolean = false;
    private var stageRef:Stage;
    private var target:Cowboy;

    public function ObjectPlacer(stageRef:Stage)
    {
        this.stageRef = stageRef;


    var Build01Timer = new Timer(1000, 1);
    var Build02Timer = new Timer(25000, 1);
    var CactiSet01Timer = new Timer(0, 1);


    Build01Timer.addEventListener(TimerEvent.TIMER, build01TimerHandler, false, 0, true);
    Build02Timer.addEventListener(TimerEvent.TIMER, build02TimerHandler, false, 0, true);
    CactiSet01Timer.addEventListener(TimerEvent.TIMER, cactiSet01TimerHandler, false, 0, true);

        addEventListener(Event.ENTER_FRAME, loop, false, 0, true);

        Build01Timer.start();
        Build02Timer.start();
        CactiSet01Timer.start();
    }


    public function loop(e:Event): void
    {
        BuildSet01();
        BuildSet02();
        CactiSet01();

    }   

    private function BuildSet01(): void
    {
        if (build01Place)
        {
        var Buildings01Right:BuildingsLeft = new BuildingsLeft(stage, 720, -624);   
        Buildings01Right.scaleX = -1;
        stageRef.addChildAt((Buildings01Right), 2);
        var target:Cowboy = new Cowboy(stage);
        var Buildings03Left:BuildingsLeft03 = new BuildingsLeft03(stage, 0, -720, target);              
        stageRef.addChildAt((Buildings03Left), 2);
        build01Place = false;


        }

    }

    private function BuildSet02(): void
    {

        if (build02Place)
        {

        var Buildings04Left:BuildingsLeft04 = new BuildingsLeft04(stage, 0, -800);
        stageRef.addChildAt((Buildings04Left), 2);
        build02Place = false;
        }
    }

    private function CactiSet01(): void
    {
        if (cactiSet01Place)
        {
            var cactus01:GScactus01 = new GScactus01(stage, 0, 300);
            stageRef.addChildAt((cactus01), 2);
            var cactus01b:GScactus01 = new GScactus01(stage, 190, 50);
            stageRef.addChildAt((cactus01b), 2);
            var cactus01c:GScactus01 = new GScactus01(stage, 660, -40);
            stageRef.addChildAt((cactus01c), 2);
            cactus01c.scaleX = -1;
            var cactus01d:GScactus01 = new GScactus01(stage, 710, 340);
            stageRef.addChildAt((cactus01d), 2);
            cactus01d.scaleX = -1;
            var cactus02:GScactus02 = new GScactus02(stage, 420, -50);
            stageRef.addChildAt((cactus02), 2);
            var cactus02b:GScactus02 = new GScactus02(stage, 600, 180);
            stageRef.addChildAt((cactus02b), 2);
            var cactus02c:GScactus02 = new GScactus02(stage, 300, 240);
            stageRef.addChildAt((cactus02c), 2);
            var cactus03:GScactus03 = new GScactus03(stage, 540, 100);
            stageRef.addChildAt((cactus03), 2);
            var cactus03b:GScactus03 = new GScactus03(stage, 30, 5);
            stageRef.addChildAt((cactus03b), 2);
            cactus03b.scaleX = -1;
            var cactus03c:GScactus03 = new GScactus03(stage, 520, 420);
            stageRef.addChildAt((cactus03c), 2);

            cactiSet01Place = false;
        }
    }



    private function build01TimerHandler(e: TimerEvent) : void
    {
        build01Place = true;
    }
    private function build02TimerHandler(e: TimerEvent) : void
    {
        build02Place = true;
    }


    private function cactiSet01TimerHandler(e: TimerEvent) : void
    {
        cactiSet01Place = true;
    }











    private function removeSelf() : void
    {
        removeEventListener(Event.ENTER_FRAME, loop);

        if (stageRef.contains(this))
        stageRef.removeChild(this); 
    }   



















}

}

Obviously there is more actionscript files that interact with these files but, these should be the only ones affected by a "hitTest"

回答1:

In regards to your Error 1009, the loop() method contains a

target.hit

reference, the only potential I see for a null pointer.

I see one real possibility: You're passing in a null to BuildingsLeft03's constructor for the target property from some external class constructing a BuildingsLeft03.

BuildingsLeft03(stage, 0, 0 null) //the null

This would make

target == null
target.hit //ERROR 1009