【问题标题】:Actionscript 3.0 Activating EventListener for an ObjectActionscript 3.0 为对象激活 EventListener
【发布时间】:2011-10-24 21:29:27
【问题描述】:

在我的 Flash 程序中,我试图在一个对象中运行一个函数。该对象使用一个名为“SkullDemon.as”的类。我试图运行的函数称为“moveSkullDemon();”此函数在“SkullDemon.as”类中编码。

我的主要文档类是“TME2d_Main.as”。在该文件中,我创建了一个 Skull Demon 类的实例,如下所示:

        public var skullD1b:SkullDemon;
        skullD1b = new SkullDemon();
        skullD1b.x = 2990.75;
        skullD1b.y = 836.95;
        skullDemonContainer.addChild(skullD1b);

存储 SkullDemon 实例的“skullDemonContainer”被放置到另一个名为“envContainer”的容器中,该容器使用以下代码行添加到屏幕:

        this.addChild(envContainer);

SkullDemon 实例被创建并加载到屏幕上就好了。当我尝试运行 SkullDemon 类中的任何函数时,就会出现问题。

如前所述,我尝试为“skullD1b”实例调用“SkullDemon.moveSkullDemon()”函数。目前,“moveSkullDemon()”函数只是将 SkullDemon 对象移动到左侧。

我尝试从 SkullDemon 的构造函数中调用此函数,但这不起作用。事实上,在 SkullDemon 的构造函数中编写的任何代码都不会在创建 Skull Demon 对象时执行。我试图在调用“moveSkullDemon()”的 SkullDemon 类中创建一个 EventListener,但它什么也没做。

我尝试了以下方法来运行“moveSkullDemon()”函数:

1:像这样从“TME2d_Main”调用“moveSkullDemon()”:

skullD1b.moveSkullDemon();

但这带来了一个错误 (#1006),说 'moveSkullDemon' 不是一个函数。

2:除了函数调用中没有括号之外,与 #1 做同样的事情:

skullD1b.moveSkullDemon;

3:在 'TME2d_Main' 中为调用其 'moveSkullDemon' 函数的 'skullD1b' 实例创建一个 EventListener:

skullD1b.addEventListener(Event.ADDED, skullD1b.moveSkullDemon);

这会引发另一个错误:“错误 #2007:参数侦听器必须为非空。”它还不断发现“空”引用错误:

    "1009: Cannot access a property or method of a null object reference.
    at classes::TME2d_Main/controlPlayer()"

我不知道为什么这个问题是指 'controlPlayer()' 方法,因为它根本不涉及 Skull Demon 实例。 'controlPlayer()' 通过 EventListener 调用,在 'TME2d_Main' 中使用此代码:

player.addEventListener(Event.ENTER_FRAME, controlPlayer);

4:为调用 move 函数的“SkullDemonContainer”创建一个 EventListener:

skullDemonContainer.addEventListener(Event.ADDED, skullD1b.moveSkullDemon);

这带来了与 #3 中相同的错误。

我这几天一直有这个问题,不知道是什么原因造成的。这是我在“moveSkullDemon()”函数中的代码:

        public function moveSkullDemon() {
        trace("skull demon moving!");

        this.x -= 5;

        // If the Player has not hit the 'floor,' increase his falling 
            //speed
        if (! floor.hitTestPoint(this.x, this.y, true)) {
            this.y += this.sdGravity;
            // The Skull Demon is not on the ground when he's not touching it
            sdOnGround = false;
        }

        // Increase the 'sdYVel' variable so that the Skull Demon will fall 
            // progressively faster down the screen. This code technically
            // runs "all the time" but in reality it only affects the Skull Demon
            // when he's off the ground.
        sdYVel += sdGravity;            

        // Increase the Skull Demon's 'y' coordinate by the 'sdYVel' value
        if (! sdOnGround) {
            this.y += sdYVel;
        }
    }

感谢您提供的任何帮助。

【问题讨论】:

  • 我应该提到,在我为我的项目使用包式系统之前,从“SkullDemon.as”的构造函数中调用“moveSkullDemon()”是可行的。某些情况迫使我使用项目系统。

标签: flash actionscript-3 class object event-listener


【解决方案1】:

如果我理解正确,您是在尝试针对您的显示对象调度一个事件,从而调用一个函数?

当你实例化你的骷髅恶魔对象时,为你想要处理的事件类型添加一个事件监听器。例如,如果您创建了一个“DemonEvent”类:

// instantiate and add event listener:
skullD1b = new SkullDemon();
skullD1b.addEventListener(DemonEvent.MOVE, moveDemonHandler);

当你想调用“moveDemonHandler”函数时,你向对象发送一个事件:

// do call this event listener, dispatch an event
// against the object
skullD1b.dispatchEvent(new DemonEvent(DemonEvent.MOVE));

您可以在事件处理程序中放置代码,或从事件处理程序代码中调用您的函数:

    protected function moveDemonHandler(event:DemonEvent):void
    {
        moveSkullDemon();
    }

    protected function moveSkullDemon():void
    {
        // ... your code here.
    }

如果你需要,例如“DemonEvent”:

package
{
    import flash.events.Event;

    public class DemonEvent extends Event
    {

        public static const MOVE:String = "MOVE";

        public function DemonEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
        {
            super(type, bubbles, cancelable);
        }

    }
}

更新

根据您的评论,听起来您正在确定放置代码以移动对象的最佳位置。您的骷髅恶魔可以自己移动,或者由于您的 TME2d_Main 类添加了骷髅恶魔,最初定位它,并且因为您需要在地板上进行测试,所以将这个逻辑放在 TME2d_Main 类中可能更有意义。

这个例子没有使用事件;但是,希望能帮助您入门。如果您希望有一个使用事件的示例,请告诉我。

这里有两个类作为示例实现:

TME2d_Main.as

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

    public class TME2d_Main extends Sprite
    {
        /** skull demon instance */
        public var skullD1b:SkullDemon;

        /** floor */
        public var floor:Sprite;

        /** constructor */
        public function TME2d_Main()
        {
            super();

            // best if implemented on addedToStage
            skullD1b = new SkullDemon();
            skullD1b.x = stage.stageWidth * 0.5;
            skullD1b.y = 1;
            addChild(skullD1b);

            // listen for enter frame
            addEventListener(Event.ENTER_FRAME, enterFrameHandler);
        }

        /** every frame, move skull demon */
        protected function enterFrameHandler(event:Event):void
        {
            // call local function of this class
            moveSkullDemon();
        }

        protected function moveSkullDemon():void
        {
            // since this TME2d_Main class defined and positioned
            // skullD1b, it probably makes sense for this class
            // to continue positioning it, especially if you need to
            // hit test again a floor, which is probably also defined
            // in this class?
            if (skullD1b.hitTestObject(floor))
            {
                // skull is on floor 
                skullD1b.sdOnGround = true;

                // end animation
                removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
            }
            else
            {
                // otherwise, skull is in air and falling
                skullD1b.y *= skullD1b.sdYVel;
            }
        }

        // if you wanted to have skull demon
        // move itself, you would call:
        //
        //     skullD1b.moveSkullDemon()
        //
        // ...but make sure that function exists
        // in SkullDemon class.

    }
}

SkullDemon.as

package
{
    import flash.display.Sprite;

    public class SkullDemon extends Sprite
    {

        /** acceleration factor */
        public var sdYVel:Number = 1.05;

        /** whether skull demon is on ground */
        public var sdOnGround:Boolean = false;

        /** constructor */
        public function SkullDemon()
        {
            super();
        }

        // if you want SkullDemon to move itself,
        // make sure you define a moveSkullDemon function:
        //
        //      public function moveSkullDemon():void
        //      {
        //      }

    }
}

【讨论】:

  • 非常感谢,杰森!我已经实现了您建议的代码。但是,我还有一个问题。我在哪里放置“moveDemonHandler()”函数?我假设这将进入“SkullDemon”类(?)。我一开始试过这个,但是当我到达这一行时:'skullD1b.addEventListener(DemonEvent.MOVE, moveDemonHandler);'编译器抱怨,发现此错误:“1180:调用可能未定义的方法 moveDemonHandler”。我尝试将处理程序和 moveDemon() 代码放入“DemonEvent”,但效果不佳。
  • 我认为您的容器所在的 TME2d_Main 看起来像是在调度和侦听事件,但 SkillDemon 类中有 moveSkullDemon 函数。取决于您是否希望 TME2d_Main 移动您的骷髅恶魔,或者您是否希望骷髅恶魔对象自行移动。现在我更好地理解了您的问题,让我尝试改进我的答案。
  • 行得通,杰森!再次感谢。我还有一个问题。对于那个很抱歉;我正在现场学习Flash。我几乎完全实现了您更新的代码。但是,我确实更改了“moveDemon”函数以迭代移动 SkullDemonContainer 中的每个 Skull Demon。我使用了一个while循环来做到这一点。当我加载 10 个骷髅恶魔时,程序似乎运行得很好。我的问题是是否有更优化的方法来做到这一点?我尝试将“当前”恶魔对象作为参数传递给“enterFrameHandler”,但它似乎只有在“事件”通过时才有效。
  • 使用循环是有道理的,您可以使用 while 或 "for each(var demo:SkullDemon in skullDemonArray" 或 "for(var i:uint = 0; i
【解决方案2】:

在您的 TME2d_Main.as 文件中,您声明您的代码是这样的。

    public var skullD1b:SkullDemon;
    skullD1b = new SkullDemon();
    skullD1b.x = 2990.75;
    skullD1b.y = 836.95;
    skullDemonContainer.addChild(skullD1b);

最后 4 行需要放在一个函数中。您不能在函数之外的类中实例化或赋值。
好吧,您可以像这样实例化,但所有其他代码都需要功能化(甚至是一个词)。

public var skullD1b:SkullDemon = new SkullDemon();

// TME2d_Main is the constructor and should be called automatically
public function TME2d_Main( ):void{
    skullD1b.x = 2990.75;
    skullD1b.y = 836.95;
    skullDemonContainer.addChild(skullD1b);
}

你最好这样做。

public var skullD1b:SkullDemon;

// TME2d_Main is the constructor and should be called automatically
public function TME2d_Main( ):void{
    skullD1b = new SkullDemon();
    skullD1b.x = 2990.75;
    skullD1b.y = 836.95;
    skullDemonContainer.addChild(skullD1b);
}

如果这不能解决问题,请发布您的完整 TME2d_Main.as 文件。

【讨论】:

  • 对不起,我没有正确复制我的代码。我按照建议的方式设置了我的“TME2d_Main.as”文件,但我没有在我的帖子中用“...”反映这一点。
  • 好吧,如果您不发布 TME2d_Main.as,我认为您不会得到很好的帮助,此时任何事情都只是猜测。只需编辑您的问题并发布即可。您有范围界定问题,如果没有该代码,我们将无法找到它。
猜你喜欢
  • 2013-01-09
  • 1970-01-01
  • 1970-01-01
  • 2015-12-27
  • 2018-11-20
  • 2010-10-02
  • 2012-07-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多