如何使 class 文件将事件处理程序应用于主舞台上除自身之外的实例或对象?

How to make a class file apply an eventhandler to instance or object on main stage asides from itself?

我是 ActionScript 3 的新手,我一直试图在 class 文件中执行上述操作。我试图在网上寻找解决方案,但我找不到合适的答案,可能是因为我没有寻找合适的搜索词等

无论如何,我正在尝试在 Adob​​e Animate CC 中的 FLA 文件中制作基本动画,"Campfire.FLA",其中在 Campfire 上按下鼠标会导致一块煤炭附着在悬浮棒上松开鼠标按钮时发光和冷却。在主时间线上,我可以很好地执行它,但我想将信息 t运行sfer 到一个 class 文件/文档文件,但无济于事。

该代码是我在 FLA 的主要时间轴第 1 帧中使用的代码,它在下面运行得非常好:

stop();
/* Instance names:
    Fire = Instance of "FireButton"; simplebutton.
    STween = Instance of "Stick Tween"; MovieClip, simple tween animation the object, "MarshmallowStick" moving.
    Stick = Instance of "Marshmallow Stick"; MovieClip.
    CoalRock = Instance of "Coal"; MovieClip.
*/
Fire.addEventListener(MouseEvent.MOUSE_DOWN, RockHot)
function RockHot(e: MouseEvent): void {
    stopPlayReverse();
    // Causes Coal and Stick to play their animation upon clicking Fire.
    STween.Stick.play();
    STween.Stick.CoalRock.play();

}
Fire.addEventListener(MouseEvent.MOUSE_UP, RockCold)
function RockCold(e: MouseEvent): void {
    STween.Stick.CoalRock.addEventListener(Event.ENTER_FRAME, playReverse, false, 0, true);
    STween.Stick.gotoAndPlay(1);
    // Upon letting go of mouse button, it causes the coal to cool down/ play reverse. Stick resets to Frame 1.

}
function playReverse(e: Event): void {
    if (STween.Stick.CoalRock.currentFrame == 1) {
        stopPlayReverse();
    // If Coal is back on Frame 1, it stops.
    } else {
        STween.Stick.CoalRock.prevFrame();
    // If Coal is not on Frame 1 it continues going reverse where it left off.
    }
}

function stopPlayReverse(): void {
    if (STween.Stick.CoalRock.hasEventListener(Event.ENTER_FRAME)) {
        STween.Stick.CoalRock.removeEventListener(Event.ENTER_FRAME, playReverse);
    // Stops the function playreverse()
    }
}

但是,在尝试将信息迁移到 ActionScript 文件时,我 运行 遇到了几个问题。首先,我尝试为上面的每个对象制作一个 ActionScript 3 class 文件,其中大部分信息都是空白的,因为我不知道如何在它们之间传递事件处理程序。 MovieClips的很多资料都没有资料,"MarshmallowStick"如下:

package  {

    import flash.display.MovieClip;


    public class MarshmallowStick extends MovieClip {


        public function MarshmallowStick() {
               // Empty, no constructor code.
        }
    }

}

对于 "Fire" Class 文件,我尝试了类似的操作:

package {

    import flash.display.*;
    import flash.events.*;
    import Coal;


    public class FireButton extends SimpleButton {
        public var CoalRock = Coal;
        public function FireButton() {
        Coalrock = new Coal ();
        this.addEventListener(MouseEvent.CLICK, RockHot)
            function RockHot(e: MouseEvent): void {
                CoalRock.play();
                trace("OK");
                trace(CoalRock);
            }
        }
    }
}

但经测试发现,该文件只是创建了一个名为CoalRock的新对象,与主舞台上的对象无关。因此,单击 FireButton 只会导致新对象播放。

我尝试制作文档 class,如下所示,在名为 "Main.as":

的文件中
package {

    import flash.display.*;
    import flash.events.*;


    public class Main extends MovieClip {
        public var Fire: FireButton;
        public var CoalRock: Coal;
        public var Stick: MarshmallowStick;
        public var STween: StickTween;

        public function Main() {
            CoalRock = new Coal();
            Fire = new FireButton();
            Stick = new MarshmallowStick();
/*          
            addChild(Fire);
            addChild(CoalRock);
            addChild(Stick);
            addChild(STween);
*/
// RIP, well it's pretty much the same code as above. Just without the nested symbols/ objects.
            Fire.addEventListener(MouseEvent.MOUSE_DOWN, RockHot)
            function RockHot(e: MouseEvent): void {
                stopPlayReverse();
                //Eye + Emblem glow
                Stick.play();
                CoalRock.play();
                trace("OK");

            }
            Fire.addEventListener(MouseEvent.MOUSE_UP, RockCold)
            function RockCold(e: MouseEvent): void {
                CoalRock.addEventListener(Event.ENTER_FRAME, playReverse, false, 0, true);
                Stick.gotoAndPlay(1);
            }
            function playReverse(e: Event): void {
                if (CoalRock.currentFrame == 1) {
                    stopPlayReverse();
                } else {
                    CoalRock.prevFrame();
                }
            }

            function stopPlayReverse(): void {
                if (CoalRock.hasEventListener(Event.ENTER_FRAME)) {
                    CoalRock.removeEventListener(Event.ENTER_FRAME, playReverse);
                }
            }
        }
    }

}

但据我测试,它只影响通过 addChild() 添加的对象。但这样做的主要目的是让脚本影响主舞台/场景中已经存在的对象。

如果你想看看它是如何播放/假设播放出来的,你可以把主要的时间线代码粘贴到一个 FLA 文件中,其中包含提供的代码的实例。

不知道Stack会怎么格式化。 / / 应该是多行注释。

这是一个复杂的问题。

你(可能)最需要的是一些封建等级制度,这样 objects 倾向于他们自己和他们的直接 children,但不会更深,也完全不会向上:

  • 容器→(接口方式)→Child→(趋向拥有children)
  • 容器←(状态事件)←Child

通常,child 不能知道它的 parent 并且应该与状态事件通信。通过这种方式,您可以将这样的 child 放入任何容器中,而不会有 child 可能向上延伸并期望不存在的 parent 结构的风险。

所以,你的问题。

第一。访问主时间线上已经存在的objects。嗯,唯一的技巧不是创建 新的 ,而是获取对现有的引用。

package
{
    // Imports.

    public class Main extends MovieClip
    {
        // If you have an instance of MarshmallowStick with the
        // instance name "Stick" on the main timeline,
        // you don't need to do anything else.
        //
        // Default publish settings are to auto-declare
        // the main timeline instance into the
        // appropriately named variable.

        public var Stick:MarshmallowStick;

P.S. 自己从 Tween 中找出 Stick

第二。要访问 Stick 中的 Coal,您需要在通讯器 class 中声明一个适当的变量。此外,将向前和向后播放所需的东西尽可能靠近它们操作的 objects 是很有意义的。

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

    public class MarshmallowStick extends MovieClip
    {
        // You don't seem to need a separate class for Coal.
        // Having it as a regular MovieClip will suffice.
        public var Coal:MovieClip;

        // Call this to play animation forward.
        public function playNormal():void
        {
            removeEventListener(Event.ENTER_FRAME, onReverse);

            gotoAndPlay(1);
            Coal.play();
        }

        // Call this to play animation backward.
        public function playReverse():void
        {
            Coal.stop();
            gotoAndPlay(1);

            addEventListener(Event.ENTER_FRAME, onReverse);
        }

        // This method does not need to be seen from the outside
        // so declare it as private rather than public.
        private function onReverse(e:Event):void
        {
            if (Coal.currentFrame > 1)
            {
                Coal.prevFrame();
            }
            else
            {
                playNormal();
            }
        }

        // Call this to stop playing into any direction.
        public function stopPlaying():void
        {
            stop();
            Coal.stop();

            removeEventListener(Event.ENTER_FRAME, onReverse);
        }
    }
}

第三。避免在函数内部声明函数。您可以阅读什么是闭包以及如何在 AS3 中处理它们,但暂时(并且可能在可预见的未来)您不需要它们。

package
{
    // Imports.

    public class Main extends MovieClip
    {
        public var Fire:SimpleButton;
        public var Stick:MarshmallowStick;

        public function Main()
        {
            Fire.addEventListener(MouseEvent.MOUSE_DOWN, makeHot);

            // The rest of the code.
        }

        function makeHot(e:MouseEvent):void
        {
            Stick.playNormal();
            trace("OK");
        }

第四。不要子class按钮。创建一个简单的 class-free 按钮并订阅其 MouseEvent.CLICKMouseEvent.MOUSE_DOWN 事件就足够了在某个知道此按钮用途的地方处理所有必要的操作。我上面已经说过了。封建等级制。按钮应该触发一个事件,然后它的持有者应该捕获该事件并做出反应。按钮本身应该不知道它在哪里,它的用途是什么,更不知道尝试做什么。