【问题标题】:(AS3) Functions(AS3) 功能
【发布时间】:2012-10-29 22:33:00
【问题描述】:

按照 MJW 的调试错误 #1009 指南,我设法修复了整个空阶段错误。但是现在初始化子弹的函数没有被调用。

片段:

if (stage) {
 init();
} else {
addEventListener(Event.ADDED_TO_STAGE, init);               
}

...

private function init(event:Event = null) {

    removeEventListener(Event.ADDED_TO_STAGE, init);
    stage.addEventListener(Event.ENTER_FRAME, shoot);


}

...

private function shoot(event:Event) {

    var bullet:EnemyBullet = new EnemyBullet();

    stage.addChild(bullet);

    bullet.x = enemy.x;
    bullet.y = enemy.y;

    bullet.theta = Math.random() * 360;

    bManager.bulletVector.push(bullet);


}

请注意,当我将 trace() 放在后两个函数中时,什么也没有发生,但第一个 sn-p 中的 addEventListener() 确实被调用了(或者我认为如此)。

【问题讨论】:

  • 1) 你确定第一个 sn-p 被调用了吗?在那里抛出一个断点/跟踪来验证。 2) 对象是否真的被添加到舞台上? Event.ADDED_TO_STAGE 仅在将对象添加到舞台时调用(有意义,对吗?)因此,如果您实际上并未将其添加到舞台,它将永远被调用
  • 你能粘贴你的整个班级吗?
  • @Apocalyptic0n3 我做了一个跟踪测试,这就是我验证它被调用的方式。那么我应该改用什么?当我将代码粘贴到第一个 sn-p 所在的 shoot 函数中时,出现错误。
  • 你从来没有回答我的第二个问题:你是要把这个加到舞台上吗?如果不是,那么stage 将始终为空,并且 Event.ADDED_TO_STAGE 将永远被调度。
  • @Apocalyptic0n3 抱歉,我正在将对象添加到舞台。我该如何初始化它?

标签: actionscript-3


【解决方案1】:

作为一般做法,stageshould not be referenced - 特别是在您的情况下,您的引用仅用于添加子弹类的实例。如果是 z-index 的问题,您可以改用一个层,将项目符号放置在显示列表中其他显示对象的顶部。

除了在单个阶段加载多个 SWF 的复杂性之外,通过将显示对象添加到它们自己的显示列表层次结构中,您的代码将成为很好的独立功能单元。或者,您可以利用控制器操纵视图的 MVC 模式。

为了让您的代码正常工作,该类必须是 SWF 的主要功能或添加到阶段。

如果是 SWF 的 main 函数,会调用init()。

否则,请确保通过 addChild() 将其添加到显示列表中。

你真的打算每帧发射一颗子弹吗?那可能是每秒 24 到 60 发子弹。您可能希望以一定的概率限制它,无论子弹是否着火。

假设这是一个战场,你的战场类被添加到舞台,它可以这样实现:

package
{
    import flash.display.Sprite;
    import flash.events.Event;

    [SWF(percentWidth = 100, percentHeight = 100, backgroundColor = 0x0, frameRate = 30)]
    public class Battlefield extends Sprite
    {
        public function Battlefield()
        {
            if (stage)
                init();
            else
                addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
        }

        protected function addedToStageHandler(event:Event):void
        {
            removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
            init();
        }
        protected function init():void
        {
            addEventListener(Event.ENTER_FRAME, frameHandler);
        }

        protected function frameHandler(event:Event):void
        {
            var odds:Number = Math.random();

            trace((odds < 0.1 ? "Fire!   " : "Skip...") + "Odds were: " + odds);
        }

    }
}

哪个会输出:

Skip... Odds were: 0.3539872486144304
Skip... Odds were: 0.742108017206192
Fire!   Odds were: 0.025597115512937307
Skip... Odds were: 0.7608889108523726
Fire!   Odds were: 0.08514392375946045 
Skip... Odds were: 0.27881692815572023

在 Stage3D 之外,我从不喜欢这种初始化模式,因为您可以像这样轻松地依赖舞台事件,如下所示:

package
{
    import flash.display.Sprite;
    import flash.events.Event;

    [SWF(percentWidth = 100, percentHeight = 100, backgroundColor = 0x0, frameRate = 30)]
    public class Battlefield extends Sprite
    {
        public function Battlefield()
        {
            addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
        }

        protected function addedToStageHandler(event:Event):void
        {
            removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
            addEventListener(Event.REMOVED_FROM_STAGE, removedFromStageHandler);

            addEventListener(Event.ENTER_FRAME, frameHandler);
        }

        protected function removedFromStageHandler(event:Event):void
        {
            removeEventListener(Event.ENTER_FRAME, frameHandler);

            removeEventListener(Event.REMOVED_FROM_STAGE, removedFromStageHandler);
            addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
        }

        protected function frameHandler(event:Event):void
        {
            var odds:Number = Math.random();

            trace((odds < 0.1 ? "Fire!   " : "Skip...") + "Odds were: " + odds);
        }

    }
}

因此,在添加到阶段后,类会启动其操作,而在从阶段移除时,类会终止其操作。

【讨论】:

  • 很好的例子,但由于某种原因,项目符号仍未初始化。
  • 子弹会有自己的初始化。在这个范围内,例如Battlefield,必须有一个在子弹范围之外的控件来发射子弹。
  • 哦,哇,忘记这一点我觉得很愚蠢。感谢您的帮助:)
【解决方案2】:

我认为问题出在第一块。

您正在检查阶段,如果阶段不为空,则使用添加到阶段的侦听器。

你应该只使用addEventListener(Event.ADDED_TO_STAGE, init);

但是,这是假设该类是 DisplayObject 子类,未添加到舞台的对象无法调用 ADDED_TO_STAGE 侦听器

【讨论】:

  • 不,他确实做得对。如果尚未将其添加到舞台,请添加侦听器。如果已将其添加到阶段,请手动触发该方法。这可能是多余的(我的猜测是在将父级添加到阶段之前发生的功能),但这是一个好习惯。
猜你喜欢
  • 1970-01-01
  • 2011-12-29
  • 2014-04-10
  • 1970-01-01
  • 1970-01-01
  • 2012-06-02
  • 2013-09-09
  • 2015-08-13
  • 2014-12-12
相关资源
最近更新 更多