如何使一个类文件应用一个 eventhandler 到实例或对象在主舞台上除了自己?

问题描述 投票:0回答:1

我对ActionScript 3很陌生,想在一个类文件中执行上面的内容,我被卡住了。我试着在网上找解决办法,但找不到合适的答案,可能是我没有找对搜索词等原因。

总之,我想在Adobe Animate CC中制作一个FLA文件 "Campfire.FLA "的基本动画,在Campfire上按下鼠标会使附着在悬浮棍上的一块煤发光,松开鼠标键后会降温。在主时间线上,我可以正常执行,但我想把信息传输到类文件文档文件中,却无济于事。

这段代码是我在FLA的主时间线Frame 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类文件,很多信息都是空白的,因为我不知道如何在它们之间沟通eventhandlers。MovieClips的很多信息都没有,"MarshmallowStick "在下面。

package  {

    import flash.display.MovieClip;


    public class MarshmallowStick extends MovieClip {


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

}

对于 "火 "类文件,我尝试了类似的东西。

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只会导致新对象的播放。

我试着在一个名为 "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);
                }
            }
        }
    }

}

但结果发现它只影响到 通过 "Main.as "添加的对象。addChild() 以及就我测试的情况来看。但这主要是为了让脚本影响主舞台场景中已经存在的对象。

如果你想看看它是如何发挥假设,你可以把主时间线代码粘贴到FLA文件中,并提供那些实例。

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

actionscript-3 adobe-animate
1个回答
0
投票

这是一个精心设计的问题。

你(可能)最需要的是一些封建等级制度,这样对象就会倾向于自己的和自己的直接子代,但不会更深,也完全不会向上。

  • 容器 → (接口方法) → 子女 → (倾向于自己的子女)
  • 容器 ←(状态事件) ← 子女

通常情况下,一个孩子一定不知道它的父体,应该用状态事件来沟通。这样,你可以把这样的孩子放到任何容器中,而不会有风险,因为这个孩子可能会向上伸手,期待一些不存在的父结构。

所以,你的问题。

首先. 访问主时间线上已经存在的对象。好吧,唯一的诀窍就是不要创建 新的 的,但要获得现有的参考。

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里面访问Coal,需要在对应的类里面声明一个合适的变量。另外,把玩东西所需要的东西向前和向后放,尽可能的靠近它们操作的对象,这是很有意义的。

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

第四次. 不要子类按钮。创建一个简单的无类按钮,并订阅它的代码就足够漂亮了。MouseEvent.CLICKMouseEvent.MOUSE_DOWN 事件,以便在某个知道这个按钮用途的地方处理所有必要的动作。上面我已经说过了。封建等级制度。按钮应该发射一个事件,然后它的持有者应该捕捉这个事件并做出反应。按钮本身不应该知道它在哪里,也不应该知道它的目的是什么,更不应该去尝试做一些事情。

© www.soinside.com 2019 - 2024. All rights reserved.