1

我正在尝试预加载具有嵌入 swf 源的 swf。但它不想工作。我尝试了简单的预加载,但进度事件仅在加载后运行。任何想法?

public class MainShell extends MovieClip 
    {       
        [Embed(source = "Main.swf")]
        public var cs:Class;
        public var hsf8z42fdfd_as32:MovieClip;
        public function MainShell()
        {
            addEventListener(Event.ADDED_TO_STAGE, initialize, false, 0, true);
        }
        private function initialize(e:Event) {
            loaderInfo.addEventListener(IOErrorEvent.IO_ERROR, error, false, 0, true);
            loaderInfo.addEventListener(ProgressEvent.PROGRESS, progress, false, 0, true);
            loaderInfo.addEventListener(Event.COMPLETE, loaded, false, 0, true);
        }
        private function progress(e:ProgressEvent) {
            var done:Number = stage.loaderInfo.bytesLoaded;
            var total:Number = stage.loaderInfo.bytesTotal;
            var w:int = done / total * 100;
            loading.TT.text = String(w);
        }
        private function loaded(e:Event) {
            loading.parent.removeChild(loading);
            hsf8z42fdfd_as32 = new cs();
            hsf8z42fdfd_as32.addEventListener(Event.COMPLETE, onComplete);
        }
        private function error(e:IOErrorEvent):void{
            trace("Error!");
        }
        public function onComplete(e:Event) {
            addChild(hsf8z42fdfd_as32);
        }


似乎进度功能仅在文件实际加载后运行一次。进度事件应该在加载时运行,那为什么不呢?

4

3 回答 3

2

您不能预加载嵌入对象。嵌入对象的概念是它们随容器一起提供。

这就好像您的 MainShell 包含 Main.swf。

这意味着一旦包含嵌入对象的类将由类加载器加载(在内存中),您将同时拥有它的所有依赖项(包括嵌入对象)。只有在执行完里面的代码之后,这就是为什么你看不到加载进度的原因。

内容加载器用于从服务器加载远程内容。有了这个,您将看到 HTTP GET 请求的进度(如果它尚未在浏览器缓存中)。

如果要显示加载进度条等,则不能使用嵌入内容。

HIH

M。

于 2012-09-24T15:17:24.980 回答
1

我回到这里分享我对这个问题的解决方案。

这实际上是可能的。但是,如果您的项目使用库资产或时间线代码,该解决方案将不会那么容易工作。该解决方案要求您的项目主要存在于 AS3 类中,因此您可能必须调整代码才能使其正常工作。

首先,您需要下载 Flex SDK ( http://www.adobe.com/devnet/flex/flex-sdk-download.html )。您将使用它来将您的 as3 类编译为 .swf(Flex 不会弄乱您的项目,不用担心)。我们将在初始设置后回到这一点。

现在,我们将在 Flex SDK 中使用一个未记录的技巧:Frame 元数据标记。http://www.bit-101.com/blog/?p=946上的博客更详细,但 Frame 标签基本上允许您嵌入类而不调用它们直到稍后时间,而不是对任何代码/嵌入。我们将在包定义之后,但在 Main 类的类定义之前坚持这一点,如下所示:

package {
    import flash.net.utils.ByteArray;
    import flash.display.Sprite;

    [SWF(width="720", height="480", frameRate="30", backgroundColor="#000000")] //we need this definition when compiling with mxmlc

    [Frame(factoryClass="com.aierou.game.Preloader")] //the factory class takes priority, so we'll use it as a preloader
    public class Main extends Sprite{

        [Embed(source="asset.swf")] //big asset to preload
        var assetClass:Class;

        public function Main(){
            // constructor code
        }
    }
}

简而言之,这告诉编译器将 .swf 分成两帧,一帧用于预加载器,另一帧用于应用程序。

现在我们需要创建预加载器类来实际预加载游戏。应该如何做到这一点的一个例子:

package com.aierou.game{
    import flash.display.DisplayObject;
    import flash.display.MovieClip;
    import flash.events.Event;
    import flash.utils.getDefinitionByName;

    public class Preloader extends MovieClip{ //should extend MovieClip for onEnterFrame action
        public function Preloader() {
            stop();
            addEventListener(Event.ENTER_FRAME,onEnterFrame);
        }

        public function onEnterFrame(e:Event){
            var total:Number = this.stage.loaderInfo.bytesTotal;
            var loaded:Number = this.stage.loaderInfo.bytesLoaded;
            if(total==loaded){
                removeEventListener(Event.ENTER_FRAME,onEnterFrame);
                nextFrame();
                init();
            }else{
                //show preloader progress
            }
        }

        private function init(){
            //Add the main class to the stage it's done this way to prevent the compiler from sticking embeds at the start
            var mainClass:Class=Class(getDefinitionByName("Container"));
            if(mainClass){
                var app:Object=new mainClass();
                addChild(app as DisplayObject);
            }
        }
    }
}

现在我们已经设置了主类和预加载器,我们准备编译我们的项目。这就是 Flex SDK 的用武之地。我们将在这部分使用命令行,因此建议将 SDK bin 文件夹添加到“路径”环境变量中。最佳实践包括在项目的根目录中设置一个 .bat 文件,以便更轻松地编译您的项目。我使用的 .bat 设置如下:

mxmlc -frame two Main -- Main.as
start /wait Main.swf

mxmlc 将编译您的项目,将主类放在一个标有“二”的新框架中。主类中的 Frame 标签也会强制编译器将预加载器放在第一帧。

如果您没有收到任何编译器错误:恭喜!您已经为您的项目添加了一个真正的预加载器!

于 2014-02-15T20:37:43.730 回答
0

尝试将 Event.COMPLETE 侦听器添加到cs实例的 contentloaderInfo 更改它

hsf8z42fdfd_as32.addEventListener(Event.COMPLETE, onComplete);

经过

hsf8z42fdfd_as32.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
于 2012-09-18T17:25:55.183 回答