16.外部画像をまとめて読み込むクラス
複数の画像を読み込みたい
今さらなんですが、、、Flex 2 SDKを使用してFLASH作品(SWFファイル)を作成しようとすると、やはりまとめて画像を読み込みたい時があります。
実は今まで適当に(ってどんなんだよ?)読み込んでいたわけですが、ある時、修正のため1枚画像を増やそうとしただけで、えらく面倒だということに気が付きました。
そんなわけで、結局外部のJPEGとかSWFなどの画像をまとめて読み込むクラスを作ってみようかな、ということになりました。
まぁ、CS3とかあれば不要でしょうけど、Flex 2 SDKを使っているのなら必須ですよね?!
こんな感じで
ざっくりどんなクラスにしたいかというと、、、
メインのスクリプトの部分で、そのクラスからオブジェクトを作成、クラスへはロードしたい画像のファイル名を入れた配列を渡す。
読み込んだ画像を配列に入れてメイン側へ返す。
こうなると、メイン側でその画像を使うとき、配列名でアクセスすることになります。
ちゃんとした名前でアクセスしたい人にはストレスかもしれません、、、
あと、画像は1枚1枚、順に読み込んでいきます。つまり、1枚読み終わってから次の画像を読み込むようにします。
嘘かホントか知りませんが、一度に読み込む − つまりいっぺんに myimage.load(URL) を記述する − のはよろしくない、というのをどこかで見たような気がしますので。
画像読み込みクラス
作ってみたのが以下のクラス。
package {
import flash.display.*;
import flash.events.*;
import flash.net.*;
public class imageloader extends Sprite {//クラス宣言
private var imageArr:Array=new Array();//画像ファイル名の配列
private var retArr:Array=new Array();//画像格納して返すための配列
private var flagfinish:Boolean=false;
private var tprog:Number;//ロードした割合(0〜1)
//////////////////////////////////////////////////////////////
public function imageloader(imagearr_hk:Array){//コンストラクタ
imageArr=imagearr_hk;
loadimages();
}
//////////////////////////////////////////////////////////////
public function loadimages():void {
var loadingstep:uint=1;
var myimg:Loader;
var imnum:uint=0;
var rate:Number;
addEventListener( Event.ENTER_FRAME, loading_EF );
function loading_EF(eventObject:Event):void {//画像のロード
if (loadingstep==1){
myimg = new Loader();
myimg.load(new URLRequest(imageArr[imnum].imagename+
"?n="+new Date().getTime()));//キャッシュ対策
loadingstep++;
}else if (loadingstep==2){
rate=myimg.contentLoaderInfo.bytesLoaded/
myimg.contentLoaderInfo.bytesTotal;
rate=(!rate?0:rate);//値がない時は0にする
tprog=(imnum+rate)/imageArr.length;//全体の進捗割合
if ( (rate >= 1)&&(myimg.contentLoaderInfo.
bytesTotal > 30) ){//1枚の読み込み完了
retArr.push({ mc:myimg , mcname:imnum });
//お好みで必要な値を入れてもいいかも
imnum++;
if (imnum == imageArr.length){
loadingstep++;
}else{
loadingstep=1;
}
}
}else if (loadingstep==3){//全ての読み込み完了
removeEventListener( Event.ENTER_FRAME, loading_EF );
flagfinish=true;
}
}
}
//////////////////////////////////////////////////////////////
public function isfinish():Object {//全体の進捗を得るメソッド
return { flagfinish:flagfinish , tprog:tprog };
}
//////////////////////////////////////////////////////////////
public function getimages():Array {//得た画像を返すメソッド
return(retArr);
}
}
}
メイン側はこんな感じで使います(必要な宣言とか略しています)。
imageArr[0]={imagename:"image/xxx1.swf" };
imageArr[1]={imagename:"image/xxx2.swf" };
imageArr[2]={imagename:"image/background.jpg" };
//オブジェクト作成(これで読み込みスタート)
var myimage:imageloader = new imageloader(imageArr);
//"onEnterFrame"みたいな繰り返し処理の中で
var res:Object=myimage.isfinish();
if (res.flagfinish){//読み込み完了していれば
retArr=myimage.getimages();//画像を得る
addChild(retArr[0].mc);
addChild(retArr[1].mc);
addChild(retArr[2].mc);
retArr[0].mc.x=100;//という感じでアクセスする
}
見ての通り、全体の画像のうちどれだけ読み込んだかを示す値は結構適当であります、、、
例えば、画像が10枚あれば、1枚目の画像が読み込まれ完了時点で0.1、2枚目完了時が0.2となります。つまり、ざっくり、枚数ベース。
で3枚目を読み込んでる途中は、その0.2+ 0.1*3枚目の読み込んだ割合 としています。
つまり、(たいていそうでしょうけど)バイト数の異なる画像を読み込むと、一定の速度で読み込んでいても、読み込み具合を示す棒(プリローダーでよく見るあれ)はスムーズに伸びません!(^^;
実行結果は、略させていただきます。
なぜって、、、大きい画像をサーバーに置くのがもったいないので、、、(^^;
ですので、3枚の画像をロードした時の実行結果画像を。
なお、画像右のテキスト表示は画像読み込みクラスではなく、メイン側で表示させています。
