2014-10-06

ActionScript3でBulkLoaderを使い複数の外部ファイルを読み込む

Flash ActionScript3で複数の外部ファイルを読み込むには、BulkLoaderが便利なようだ。使ってみる。

https://github.com/arthur-debert/BulkLoader で最新版を取得して、srcに展開し、以下をビルド。

package {
    import flash.display.Bitmap;
    import flash.display.MovieClip;
    import flash.display.Sprite;
    import flash.events.Event;
    import br.com.stimuli.loading.BulkLoader;
    import br.com.stimuli.loading.BulkProgressEvent;
    import flash.text.TextField;
    import flash.text.TextFormat;
    import flash.utils.ByteArray;
    import org.as3wavsound.WavSound;
    import org.as3wavsound.WavSoundChannel;

    /**
     * ...
     * @author foo
     */
    [SWF(width = "410", height = "580", frameRate = "30", backgroundColor = "0x888888")]
    public class Main extends Sprite {
        private var loader:BulkLoader;

        public function Main():void {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }

        private function init(e:Event = null):void {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            // entry point

            loader = new BulkLoader('main');
            loader.addEventListener(BulkProgressEvent.COMPLETE, onLoadComplete);
            loader.addEventListener(BulkProgressEvent.PROGRESS, onLoadProgress);
            loader.add('test.jpg', { id:'bg1', priority:20 } );
            loader.add('test.png');
            loader.add('test.swf', { pausedAtStart:true } );
            loader.add('test.txt');
            loader.add('test.wav', { id:'bgm1', type:BulkLoader.TYPE_BINARY } );
            loader.start();
        }

        private function onLoadProgress(e:BulkProgressEvent):void {
            // https://github.com/arthur-debert/BulkLoader/wiki/Reporting-Loading-Progress
            // trace('ratio:'+e.percentLoaded+' (loaded'+e.bytesLoaded+', total:'+e.bytesTotal+')'); bytesTotalが0のまま
            trace('items loaded:'+e.itemsLoaded+', total:'+e.itemsTotal);
        }

        private function onLoadComplete(e:BulkProgressEvent):void {
            // https://github.com/arthur-debert/BulkLoader/wiki/Accessing-Loaded-Content

            addChild(loader.getBitmap('bg1'));

            var chara:Bitmap = loader.getBitmap('test.png');
            chara.y = 580-252;
            addChild(chara);

            var mc:MovieClip = loader.getMovieClip('test.swf');
            mc.x = 310;
            addChild(mc);

            var theTxt:String = loader.getText('test.txt');
            var tf:TextField = new TextField();
            tf.defaultTextFormat = new TextFormat('Noto Sans Japanese Regular', 16, 0x000000);
            tf.wordWrap = true;
            var speechBaloon:MovieClip = new MovieClip();
            speechBaloon.graphics.beginFill(0xffffff, 0.5);
            speechBaloon.graphics.drawRoundRect(15, 15, 380, 200, 5, 5);
            speechBaloon.graphics.endFill();
            addChild(speechBaloon);
            tf.x = 20;
            tf.y = 20;
            tf.width = 370;
            tf.height = 190;
            tf.text = theTxt;
            addChild(tf);

            var snd:WavSound = new WavSound(loader.getBinary('test.wav'));
            var chnl:WavSoundChannel = snd.play();
        }
    }
}

動作はしている。swfのpausedAtStart : true は効いてないような。

使用した素材は以下。

外部音声はライセンス料問題があるのでwav。swfに内蔵させるんだったらmp3でいいんだけど。

参考になった資料

Progress Percentage

長いロード時間を待つには、ロード進捗率表示がほしい。 上のソースだと「ロード中アイテムの個数」しか表示しないので大ざっぱ過ぎる。

パーセンテージを表示するには https://github.com/arthur-debert/BulkLoader/wiki/Reporting-Loading-Progress によると各アイテムに weight を指定しろ、と書いてある。

ソースを以下にすると%表示できた。 ここではweightの数値は ファイルの容量(単位:バイト)にしているが、細かすぎる気はするので、単位をKBにしてよいと思う。

        private function init(e:Event = null):void {
            ...
            loader.add('test.jpg', { id:'bg1', priority:20, weight:9580 } );
            loader.add('test.png', { weight:36459 } );
            loader.add('test.swf', { pausedAtStart:true, weight:996 } );
            loader.add('test.txt', { weight: 486 } );
            loader.add('test.wav', { id:'bgm1', type:BulkLoader.TYPE_BINARY, weight:225164 } );
            ...
        }

        private function onLoadProgress(e:BulkProgressEvent):void {
            // https://github.com/arthur-debert/BulkLoader/wiki/Reporting-Loading-Progress
            // trace('ratio:'+e.percentLoaded+' (loaded'+e.bytesLoaded+', total:'+e.bytesTotal+')'); //bytesTotalが0のまま
            //trace('items loaded:'+e.itemsLoaded+', total:'+e.itemsTotal); //ロード中アイテムの個数
            trace('ratio:'+int(e.weightPercent*100)+' (loaded item'+e.itemsLoaded+', total item:'+e.itemsTotal+')');
        }

remove

以下のように書くと、swfのpausedAtStartも効くようになった。swf再生のためにplay()が必要。 使用しなくなったらremove()すればよいらしい。EventListenerはremoveやremoveAllで消えないらしいので個別にremoveEventListener()したほうがよいようだ。参考: https://github.com/arthur-debert/BulkLoader/wiki/Memory-Management

        private function onLoadComplete(e:BulkProgressEvent):void {
            // https://github.com/arthur-debert/BulkLoader/wiki/Accessing-Loaded-Content
            loader.removeEventListener(BulkProgressEvent.COMPLETE, onLoadComplete);
            loader.removeEventListener(BulkProgressEvent.PROGRESS, onLoadProgress);

            var bg:Bitmap = loader.getBitmap('bg1');
            var chara:Bitmap = loader.getBitmap('test.png');
            var mc:MovieClip = loader.getMovieClip('test.swf');
            var theTxt:String = loader.getText('test.txt');
            var wav:ByteArray = loader.getBinary('test.wav');

            loader.removeAll(); //loader.getXXX()はできなくなるが、loader.add()は可能
            loader = null;
            BulkLoader.removeAllLoaders(); //loader.add()も不可


            addChild(bg);

            chara.y = 580-252;
            addChild(chara);

            mc.x = 310;
            addChild(mc);
            mc.play();

            var tf:TextField = new TextField();
            tf.defaultTextFormat = new TextFormat('Noto Sans Japanese Regular', 16, 0x000000);
            tf.wordWrap = true;
            var speechBaloon:MovieClip = new MovieClip();
            speechBaloon.graphics.beginFill(0xffffff, 0.5);
            speechBaloon.graphics.drawRoundRect(15, 15, 380, 200, 5, 5);
            speechBaloon.graphics.endFill();
            addChild(speechBaloon);
            tf.x = 20;
            tf.y = 20;
            tf.width = 370;
            tf.height = 190;
            tf.text = theTxt;
            addChild(tf);

            var snd:WavSound = new WavSound(wav);
            var chnl:WavSoundChannel = snd.play(0,999);
        }

0 件のコメント:

コメントを投稿

人気記事