as3 - 错误#2007:参数hitTestObject必须是非null - 找到错误,需要解决方案

时间:2014-11-30 22:23:34

标签: actionscript-3 flash variables global-variables

我完成了腿部工作并追查了问题。当我打电话

if (enemy.hitTestObject(bullet)){

bullet是null。

我认为问题是由于

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

是在函数内部创建的,而不是在类中创建为公共var。但是,当我将这行代码与其他公共变量一起移动(并将其更改为公共变量)时,它会打破子弹射击。

所以,问题是,我怎样才能使子弹不为空?

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);
        }
    }
}
}

感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

问题在于onTick()您尝试使用全班bullet变量。这是永远不会定义的,因为在shootBullet()中您使用var关键字定义新变量并定义其类型:

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

你需要这样做:

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

var关键字创建一个全新的局部变量,无论某个类是否已包含具有该名称的属性,该函数将从该点开始使用该变量。

但是,为什么你只测试最后创建的子弹?我会假设您要检查任何子弹是否击中了任何敌人,如下所示:

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

在这种情况下,您可以完全删除类范围的bullet变量。

答案 1 :(得分:0)

你要做的是定义变量两次。 首先在课程的根目录中;

public var bullet:Bullet;

然后在shootBullet功能中获得第二名。

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

所以你最终得到两个变量,一个在根中,另一个在函数部分。 如果在函数中调用变量,它将在函数扇区中返回一个变量。 如果你在其他地方打电话,你将拥有全班的。 试着写

bullet = new Bullet(....) 

而不是

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