在 EXIT_FRAME 上的 Actionscript 3.0 影片剪辑修改

Posted

技术标签:

【中文标题】在 EXIT_FRAME 上的 Actionscript 3.0 影片剪辑修改【英文标题】:Actionscript 3.0 Movieclip modification on EXIT_FRAME 【发布时间】:2015-11-05 12:44:02 【问题描述】:

我一直在尝试解决这个令人费解的 Flash AS3 问题。我有一个想法,这可能是 Flash 播放器的一个错误,但也许您可以了解一些情况。

我在 Flash 中有一个电影剪辑,它是 10 帧的星形,另外 10 帧是圆形,然后是另外 10 帧的方形,之后它将 gotoAndPlay(1) 重播动画。这个 MovieClip 扩展了一个我称之为 FlipClip 的 AS3 类。

FlipClip 中有一个名为reverseClip 的函数。此函数的目的是每次 Flash 启动 EXIT_FRAME 事件时围绕轴翻转某些图形子级。

public function FlipClip()
    
        //as soon as this is instantiated, add the eventListener
        addEventListener(Event.EXIT_FRAME,flipTheClip);
    

    public function flipTheClip(e:Event)
    

        trace("currentFrame = " + currentFrame);

        //for sake of simplicity, we will flip every child
        for (var i=0; i<numChildren; i++)
        

            var targetClip = getChildAt(i);
            var axis = 10;

            //if the target child has not already been flipped...
            if (Math.abs(targetClip.scaleX) / targetClip.scaleX != -1)
            

                //reverse the child's direction with scaleX and move based on the axis
                targetClip.scaleX *=  -1;
                var dist:Number = targetClip.x - axis;
                targetClip.x = axis - dist;

            
        
    

显而易见的结果是,每退出一帧,所有图形元素都会围绕 x=10 水平翻转,并且每十帧,MovieClip 的形状就会从星形变为圆形,再变为方形。对吧?

没有。

MovieClip 确实围绕该轴成功翻转,但随后出现了一个奇怪的问题。动画停止。 MovieClip 就像一颗永恒的明星。 Flash 甚至没有意识到动画已经停止,因为我们一遍又一遍地得到这个输出;

currentFrame = 1
currentFrame = 2
currentFrame = 3
currentFrame = 4
...
currentFrame = 30
currentFrame = 1

一直到 30,然后又回到 1。剪辑仍在播放,但不知何故图形元素没有更新!

这是 Flash 播放器的问题吗?这是代码的问题吗?任何帮助表示赞赏!

我已将 .fla 和 .as 的文件上传到 Dropbox。我还在研究如何嵌入类似的东西,但现在我希望这个链接对你有用。

https://www.dropbox.com/sh/hcljutesblichpp/AABKQ4Kn8OTwfTaeh0I3nnOZa?dl=0

更新:

如果我将每个单独的形状转换为父影片剪辑中的影片剪辑,它会正确播放。但是,对于复杂的动画,这不是非常有效的内存或可行的。希望这些信息可以帮助您解决问题。

【问题讨论】:

它是如何从一个形状变成另一个形状的?你能分享你的.fla吗?我认为那将是最简单的。有时当您通过代码修改对象时,它可以覆盖时间线的东西。你为什么使用 EXIT_FRAME 而不是 ENTER_FRAME?你真的需要学习如何使用分号,这很重要。 urk html 不是我的强项,而且我完全没有在线共享文件的经验。我会尝试,如果您仍然无法访问它,请告诉我,我会尝试不同的方法 我使用 EXIT_FRAME 而不是 ENTER_FRAME 的原因是我注意到在应用函数之前渲染子级的问题,使他们在显示列表执行其操作时面临错误的方式。 EXIT_FRAME 似乎解决了这个问题。 【参考方案1】:

有几件事你需要注意。

    您不需要像往常一样根据 numChildren 翻转元素 返回 1,因为在每一帧上你都会得到一个孩子。 您也不需要检查其他条件 Math.abs(targetClip.scaleX) / targetClip.scaleX != -1 设置 翻动。 您还需要使用 ENTER_FRAME 而不是 EXIT_FRAME。 ENTER_FRAME 适用于当前帧,而 EXIT_FRAME 适用于 上一帧。

使用下面的代码。

package 


    import flash.display.MovieClip;
    import flash.events.*;
    import flash.utils.setTimeout;

    public class FlipClip extends MovieClip
    

        var mInstance
        var prevX;

        public function FlipClip()
        
            //as soon as this is instantiated, add the eventListener
            addEventListener(Event.ENTER_FRAME,flipTheClip);
             mInstance = this;
            //mInstance.visible  = false;
        



        public function flipTheClip(e)
        

            this.scaleX *=  -1;
            prevX = this.x;
            if(this.scaleX < 0)
                this.x = prevX + this.width
            else
                this.x = prevX - this.width
        

    


将上述代码粘贴到 FlipClip.as 文件中,并将帧速率更改为 1。 您需要根据您的要求更新moviClip 位置。

希望以上答案能解决您的问题。

【讨论】:

我没有为父动画剪辑设置scaleX = -1 的原因是我希望能够翻转父动画中的某些子元素,同时保持其他子元素不变。抱歉,我对此并不完全清楚。【参考方案2】:

您需要在播放动画之前移除 EXIT_FRAME 的监听器。此外,您在此处翻转您的电影剪辑,但未添加任何播放代码。

将以下代码粘贴到您的 FlipClip.as 文件中。

package 


    import flash.display.MovieClip;
    import flash.events.*;
    import flash.utils.setTimeout;

    public class FlipClip extends MovieClip
    

        var mInstance

        public function FlipClip()
        
            //as soon as this is instantiated, add the eventListener
            addEventListener(Event.EXIT_FRAME,flipTheClip);
             mInstance = this;
            mInstance.visible  = false;
        

        private function playallAnimation()
        
            this.gotoAndPlay(1);
        

        public function flipTheClip(e)
        
            removeEventListener(Event.EXIT_FRAME,flipTheClip);

            //for sake of simplicity, we will flip every child
            for (var i=0; i<numChildren; i++)
            

                var targetClip = getChildAt(i);
                var axis = 10;

                //if the target child has not already been flipped...
                if (Math.abs(targetClip.scaleX) / targetClip.scaleX != -1)
                
                    //reverse the child's direction with scaleX and move based on the axis
                    targetClip.scaleX *=  -1;
                    var dist:Number = targetClip.x - axis;
                    targetClip.x = axis - dist;

                
            
            setTimeout(function()
            
                mInstance.visible  = true;
                playallAnimation();
            ,200);
        

    


希望这对你有用。

【讨论】:

我将此代码应用到 FlipClip.as 文件,但它没有产生我希望的结果。我想要的结果是,MovieClip 将以翻转的外观重复播放,几乎就像我刚刚设置了 MovieClip 的 scaleX = -1。但我认为你可能会对setTimeout... 要翻转,您需要添加更多逻辑,这些逻辑基本上每次都可以扩展。根据您的代码movileClip第一次翻转,因为x的比例值已经设置为-1。在movieClip中翻转注册点后永远不会改变所以如果你想每次更新它,你需要在每次迭代时计算scaleX位置和x位置值。 如何在代码中实现这一点?我不完全明白

以上是关于在 EXIT_FRAME 上的 Actionscript 3.0 影片剪辑修改的主要内容,如果未能解决你的问题,请参考以下文章

编写高质量代码:Web前端开发修炼之道pdf

程序员应该如何开始使用Flash / Flex / ActionScript?

Jsonp的js实现,跨域请求,同源策略机制

求教json的有关问题,google库gson的bug有关问题

Windows 上的 WaitOnAddress() 在 Linux 上的完全等价物是啥?

resignFirstResponder 到不再出现在屏幕上的 UITableViewCells 上的 UITextViews