0
votes

I've done the leg work and traced down the problem. When I call

if (enemy.hitTestObject(bullet)){

bullet is null.

I believe the problem is caused because

var bullet:Bullet = new Bullet(stage, player.x, player.y, player.rotation);

is created inside of a function instead of being created as a public var in the class. However, when I move this line of code up with the other public vars (and change it to public), it breaks the bullet shooting.

So, the question is, how can I make bullet not null?

Main.as:

package 
{

import flash.display.MovieClip;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.display.Stage;
import flash.events.Event;
import flash.events.MouseEvent;


public class zombiestandoffMain extends MovieClip 
{
    public var army:Array;
    public var enemy:Enemy;
    public var player:Player;
    public var bullet:Bullet;
    public var gameTimer:Timer;
    public var crosshair:Crosshair;
    public var bulletList:Array = []; //new array for the bullets



    public function zombiestandoffMain() 
    {
        army = new Array();
        var newEnemy = new Enemy( 100, -15 );
        army.push( newEnemy );
        addChild( newEnemy );

        player = new Player(stage, 400, 500);
        stage.addChild( player );


        crosshair = new Crosshair();
        addChild( crosshair );
        crosshair.x = mouseX;
        crosshair.y = mouseY;

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

        stage.addEventListener(MouseEvent.CLICK, shootBullet, false, 0, true);
        stage.addEventListener(Event.ENTER_FRAME, loop, false, 0, true); //add an EventListener for the loop
        function loop(e:Event):void //create the loop function
        {
            if(bulletList.length > 0) //if there are any bullets in the bullet list
            {
                for(var i:int = bulletList.length-1; i >= 0; i--) //for each one
                {
                    bulletList[i].loop(); //call its loop() function
                }
            }
        }
        function shootBullet(e:MouseEvent):void
        {
            var bullet:Bullet = new Bullet(stage, player.x, player.y, player.rotation);
            bullet.addEventListener(Event.REMOVED_FROM_STAGE, bulletRemoved, false, 0, true); //triggers the "bulletRemoved()" function whenever this bullet is removed from the stage
            bulletList.push(bullet); //add this bullet to the bulletList array  
            stage.addChild(bullet);
        }

        function bulletRemoved(e:Event):void
        {
            e.currentTarget.removeEventListener(Event.REMOVED_FROM_STAGE, bulletRemoved); //remove the event listener so we don't get any errors
            bulletList.splice(bulletList.indexOf(e.currentTarget),1); //remove this bullet from the bulletList array
        }








    }

    public function onTick( timerEvent:TimerEvent ):void 
    {
        if ( Math.random() < 0.1 )
        {
            var randomX:Number = Math.random() * 400;
            var newEnemy:Enemy = new Enemy( randomX, -15 );
            army.push( newEnemy );
            addChild( newEnemy );
        }
        crosshair.x = mouseX;
        crosshair.y = mouseY;

        for each ( var enemy:Enemy in army ) 
        {
             enemy.moveDownABit();
            trace(enemy);
            trace(bullet);
            if (enemy.hitTestObject(bullet)){
                    trace("hit!");
                }



        }
    }
}
}

Bullet.as

package
{
import flash.display.Stage;
import flash.display.MovieClip;
import flash.events.Event;

public class Bullet extends MovieClip
{
    private var stageRef:Stage;
    private var speed:Number = 10;
    private var xVel:Number = 0;
    private var yVel:Number = 0;
    private var rotationInRadians = 0;

    public function Bullet(stageRef:Stage, X:int, Y:int, rotationInDegrees:Number):void
    {
        this.stageRef = stageRef;
        this.x = X;
        this.y = Y;

        this.rotation = rotationInDegrees;
        this.rotationInRadians = rotationInDegrees * Math.PI / 180;
    }

    public function loop():void
    {
        xVel = Math.cos(rotationInRadians) * speed;
        yVel = Math.sin(rotationInRadians) * speed;

        x += xVel;
        y += yVel;

        if(x > stageRef.stageWidth || x < 0 || y > stageRef.stageHeight || y < 0)
        {
            this.parent.removeChild(this);
        }
    }
}
}

Thank you for any help!

2
How does it break the bullet shooting? Does it break creation, movement, enemy hitting, or something else? - puggsoy
It actually breaks the whole game now that I rechecked. When I move it to a public var I get the error "Error #1009: Cannot access a property or method of a null object reference." referenced to that line of code. - jdfinch3

2 Answers

2
votes

The issue is that in onTick() you're trying to use the class-wide bullet variable. This is never defined, because in shootBullet() you're defining a new variable by using the var keyword and defining its type:

var bullet:Bullet = new Bullet(stage, player.x, player.y, player.rotation);

You need to instead do this:

bullet = new Bullet(stage, player.x, player.y, player.rotation);

The var keyword creates a brand new local variable, regardless of whether a class already contains a property with that name, and the function will from that point on use that variable.

However, why are you only testing with the last bullet created? I would assume that you want to check if any bullet hits any enemy, like so:

for each ( var enemy:Enemy in army ) 
{
    enemy.moveDownABit();
    for each ( var bllt:Bullet in bulletList)
    {
        if (enemy.hitTestObject(bllt)){
            trace("hit!");
        }
    }
}

In that case you could remove the class-wide bullet variable altogether.

0
votes

What you do is defining a variable two times. First in the root of class;

public var bullet:Bullet;

Then second in shootBullet function.

function shootBullet(e:MouseEvent):void
{
     var bullet:Bullet = new Bullet(stage, player.x, player.y, player.rotation);
}

So you end up having two variables, one in the root, other in the function section. If you call your variable in function, it will return one in function sector. If you call elsewhere, you'll have class-wide one. Try writing

bullet = new Bullet(....) 

instead of

var bullet:Bullet = new Bullet(....)