【问题标题】:does the display index effect the scope of an object?显示索引是否影响对象的范围?
【发布时间】:2010-12-30 23:57:21
【问题描述】:

只是想知道索引是否会影响对象的范围,因为我正在创建游戏,并且由于某种原因,我收到如下错误

TypeError: Error #1009: Cannot access a property or method of a null object reference.
    at com.objects::Torret/updateObject()
    at com.objects::EngineApi/loop()

取决于我将对象放在舞台上的哪个位置。我可以防止这个错误发生。我所要做的就是更改或删除以下代码。

eApi.setChildIndex(this, (eApi.numChildren - 1));

我的舞台上不断有物体进出,所以这段代码可以防止我的物体落到新物体下面。只有一个对象会引发此错误,那就是我的 Turret 类。另一个类是我的船类。 turret 类持有对 ship 类的引用,因此它可以向它射击。

炮塔类是唯一抛出此错误的类。下面是我的两个类的代码。是的,我知道我拼错了炮塔。谢谢

package com.objects{
    import flash.events.Event;

    public class Torret extends gameObject{

        public var currentAngle:Number;
        protected var newAngle:Number;
        public var shoot:Boolean = false;
        public var autoRotate:Boolean = false;
        public var updated:Boolean = false;
        public var target:Avatar;
        public var enemyLock:Boolean = false;
        public var attackDelay:Number;
        public var delay:Boolean = false;
        public var wielder;
        public var smokeDelay:Number = 500;

        public function Torret():void
        {
            health = 1;
            maxHealth = 1;
            currentAngle = rotation;
            newAngle = currentAngle;
            lastTime = getTime();
        }

        public function Hit(dmg:Number = .01):void {
            if(health > 0)
                health -= dmg;

            if(health < 0)
                health = 0;
        }

        override public function updateObject():void
        {
            eApi.setChildIndex(this, (eApi.numChildren - 1));
            if(health <= 0)
            {
                dead = true;
                blowUp();
            }

            if(y > 949)//If boss doesnt work, this is why
            {
                garbage = true;
            }
            if(!dead)
            {

                if(wielder)
                {
                    scaleX = wielder.scaleX;
                    scaleY = wielder.scaleY;

                }
                if(currentAngle != newAngle || autoRotate == true)
                {
                    rotation += 3;
                    currentAngle = rotation;
                    updated = false
                }
                else
                {
                    updated = true
                }

                if(shoot)
                {
                    if((getTime() - lastTime) > attackDelay && delay == true)
                    {
                        var stingerlaser = new StingerLaser();
                        stingerlaser.laserDir = rotation;
                        stingerlaser.x = x;
                        stingerlaser.y = y;
                        eApi.addGameChild(stingerlaser);
                        lastTime = getTime();
                    }
                }

                if(enemyLock)
                {
                    var dx = target.x - x;
                    var dy = target.y - y;
                    var angle = Math.atan2(dy,dx);
                    rotation = angle * 180/Math.PI;
                }
            }
        }

        protected function blowUp():void
        {
            if((getTime() - lastTime) > smokeDelay)
            {
                var smoke:MissileSmoke = new MissileSmoke();
                smoke.x = x;
                smoke.y = y;
                smoke.dir = -1;

                eApi.addGameChildAt(5,smoke);
                eApi.setChildIndex(smoke, (eApi.numChildren - 4));
                lastTime = getTime();
            }

        }

        protected function degreesToRadians(degrees:Number):Number {
            return degrees * Math.PI / 180;
        }

        protected function rotate(angle:Number):void
        {
            newAngle = angle;
        }
    }
}

下面是我的船级

package com.objects{

    import flash.display.MovieClip

    public class Avatar extends gameObject {

        public var targets:Array;
        public var delay:Number = 3000;
        public var weapon:Number = 1;

        public function Avatar():void
        {
            rotation = -90;
            lastTime = getTime();
            targets = new Array();
        }

        override public function Attack(dir:Number = -40):void
        {
            switch(weapon){

                case 1:
                    var bullet1:Bullet = new Bullet();
                    bullet1.wielder = this;
                    bullet1.x = x + 35;
                    bullet1.y = y + 30;
                    bullet1.bulletDir = rotation;
                    eApi.addGameChild(bullet1);

                    var bullet2:Bullet = new Bullet();
                    bullet2.bulletDir = rotation;
                    bullet2.wielder = this;
                    bullet2.x = x - 35;
                    bullet2.y = y + 30;
                    eApi.addGameChild(bullet2);
                break;
                case 2:
                    if((getTime() - lastTime) > delay)
                    {
                        var missle = new Missile();
                        missle.x = x;
                        missle.y = y;
                        missle.wielder = this;
                        eApi.addGameChildAt((eApi.numChildren - 2),missle);
                        lastTime = getTime();
                    }
                break;
                default:
            }
        }

        public function Hit():void
        {
            trace("ouch");
        }

        override public function updateObject():void
        {
            eApi.setChildIndex(this, (eApi.numChildren - 1));
        }
    }
}

只是想让你们知道,updateObject 是我所有对象的循环。我有一个集中式循环,在该循环中它调用已放置在舞台上的一组对象。它们都包含方法 updateObject。更新对象的状态。 addGameChild() 是一个封装的 addChild() ,它不仅将对象添加到舞台上,而且将它放在一个数组中,以便可以调用它的 updateObject() 方法。它还用于使垃圾收集更容易。

【问题讨论】:

  • 什么是eApi?在某些时候它可以为空吗?当您执行 eApi.numChildren - 1 时,您确定其中几乎有一个孩子吗?

标签: flash actionscript-3 actionscript


【解决方案1】:

首先我认为使用addGameChildAt 是不必要的,因为您不需要额外的数组来存储您的对象以在它们上调用updateObject。

for(var i:int;i<numChildren;i++) { gameObject(getChildAt(i)).updateObject(); }

那么我建议你的类名以大写字母开头,即GameObject,方法名应以小写字母开头,即attack()

我建议您在设置索引之前检查您的对象对 eApi 的引用是否存在(不为空)并且您的对象是 eApi 的一部分

if(eApi && eApi.contains(this)) { eApi.setChildIndex(this, (eApi.numChildren - 1)); }

我想知道你为什么要使用setChildIndex,因为我认为有一个常量循环在当前是eApi 子对象的对象上调用updateObject,因此你不断移动updateObject 方法为的对象当前执行到顶部,这似乎没有意义?

【讨论】:

    猜你喜欢
    • 2016-10-11
    • 2019-04-24
    • 1970-01-01
    • 1970-01-01
    • 2019-10-31
    • 1970-01-01
    • 2011-09-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多