Archive for the ‘Flashとおやつのゼミ’ Category
BulkLoader
BulkLoaderをご存知ですか?
私は気になっていたものの、自作したクラスに執着していて使う機会がありませんでした。
Flashを制作していると、更新性や設計のし易さから外部の資源(テキストや画像)を読み込んでコンテンツを展開することがよくあります。
しかしながら、この流れを組むだけでもソースコードはそれなりの行数を占めてしまい、また書き方も人それぞれです。
そこで今回このBulkLoaderをご紹介する理由は2つあります。
まず1点は高機能でありながら、使う側は少ないコードで実現できるということです。
テキストソースを読み込む時は一般的にURLLoaderクラスを用います。
また外部イメージソースに対してはLoaderクラス、flvにはNetConnectionクラスやNetStreamクラスもしくはFLVPlaybackクラス・・・
これらを目的別にインポートしてインスタンスを生成し、各種挙動に応じたイベントを登録する訳ですが、
初心者の方にはそれだけで「今期」の「根気」が尽きてしまい、肝心のコンテンツ制作に使う根気がなくなってしまいます。
勿論これらはそれぞれ意味があって独立したクラスとして成り立っているのですが、
それらを統一したクラスにすることで、メインのクラスは驚くほどシンプルになります。
根気もまだ残っているハズです!←重要
2点目は「外部ファイル読み込み」という同じ目的に対して、「ソースを書く人によりバラバラな書き方になってしまわない」ので、誰がそのソースを見ても瞬時に理解できるということです。
これも非常に重要な要素です。
「誰が見ても」分かるというのは、当然自分が見ても分かるということだと思います。
私は特別記憶力が少ないことが自慢の草食男子ですが、自分で書いたソースも1週間後には赤の他人のソースな訳ですから。独自の俺TUEEEEEクラスなんて望んでいないんです。私は。
また、悲惨なことに本当に他人が制作したクラスを、「初期の開発者が逃げた」等の理由でやむなく解読しなければならない屈辱的条件が成立してしまった場合、インポートされているクラスの中に、見覚えのあるクラスがあると、想像以上にホッとする物です。多分。
つまり2点とも自分の為であり、万が一自分のオケツを拭いてくれる神の為でもある訳です。
以上の理由から今回BulkLoaderを紹介させていただきたく存じます。
普通にLoaderクラスを用いて画像を読み込む場合は以下の様なソースになるかと思われます。
これはたった1枚の画像であるからこそ、画像のURLもハードコーディングされており一見問題ないように見えます。がしかし!通常お客様は数十枚もしくは100枚を超える画像を更新性のある形で読み込む仕様をご提案されます。
そんな時、ソースコード内に全てのURLを記述することはまず有りえませんし、なによりLoaderクラスに対しても、それらの画像を全て読み込む様なロジックを設けなければなりません。
package {
import flash.display.Sprite;
import flash.display.Loader;
import flash.events.Event;
import flash.net.URLRequest;
public class FlashTest extends Sprite {
private var loader:Loader;
private var urlRequest:URLRequest;
public function FlashTest() {
// write as3 code here..
var url:String = 'http://works.mztm.jp/kobashi/sample/img/image0.jpg';
urlRequest = new URLRequest(url);
loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
loader.load(urlRequest);
}
private function onComplete (e:Event):void {
addChild(loader);
}
}
}
Loader – wonderfl build flash online
そこで満を持して登場するのが、複数のリクエストを管理する俺TUEEEEEクラス!
ではなく。万国共通?BulkLoaderクラスです。
Bulk(大量)という言葉からも分かるように、こういったケースで使うのが最も効果的です。
BulkLoaderクラスのパッケージはhttp://code.google.com/p/bulk-loader/からダウンロードできます!
package{
import br.com.stimuli.loading.BulkLoader;
import br.com.stimuli.loading.BulkProgressEvent;
import br.com.stimuli.loading.loadingtypes.LoadingItem;
import flash.events.*;
import flash.display.*;
public class Main extends MovieClip{
public var loader:BulkLoader;
public function Main () : void {
loader = new BulkLoader('bulkLoader');
loader.add('http://works.mztm.jp/kobashi/sample/img/image0.jpg', {id:'image0', type:BulkLoader.TYPE_IMAGE, preventCache:true});
loader.add('http://works.mztm.jp/kobashi/sample/img/image1.jpg', {id:'image1', type:BulkLoader.TYPE_IMAGE, maxTries:5});
loader.add('http://works.mztm.jp/kobashi/sample/img/image2.jpg', {id:'image2', type:BulkLoader.TYPE_IMAGE, weight:100 / 4});
loader.add('http://works.mztm.jp/kobashi/sample/img/image3.jpg', {id:'image3', type:BulkLoader.TYPE_IMAGE, priority:100});
loader.addEventListener(Event.COMPLETE, onAllLoaded);
loader.addEventListener(ProgressEvent.PROGRESS, onAllProgress);
loader.start();
}
public function onAllProgress (e:BulkProgressEvent):void {
trace('onAllProgress');
}
public function onAllLoaded (e:Event):void {
trace('onAllLoaded');
var sp:Sprite;
for each (var item:LoadingItem in loader.items) {
trace(item.id);
trace(item.type);
switch (item.type) {
case 'image' :
sp = new Sprite();
sp.addChild(loader.getBitmap(item.id));
sp.addEventListener(MouseEvent.MOUSE_DOWN, function (e:MouseEvent):void {
var sp:Sprite = e.target as Sprite;
addChild(sp);
sp.startDrag();
});
sp.addEventListener(MouseEvent.MOUSE_UP, function (e:MouseEvent):void {
var sp:Sprite = e.target as Sprite;
addChild(sp);
sp.stopDrag();
});
addChild(sp);
break;
}
}
//addChildAt(loader.getBitmap('http://works.mztm.jp/kobashi/sample/img/image0.jpg'), 0);
}
}
}
以下はBulkLoaderクラスの派生クラスであるLazyXMLLoaderのサンプルです。
Lazyとはだらだら、ぐだぐだ、ごろごろとすることらしいですが。
私は「ゆとり」Loaderと呼んでいます。
それは以下を見ていただくことで実感されるでしょう。
外部のxmlに特定のルールでノードを記述します。
<?xml version="1.0" encoding="utf-8"?> <data> <files> <file> <id>img0</id> <type>image</type> <url>http://works.mztm.jp/kobashi/sample/image/image0.jpg</url> </file> <file> <id>img1</id> <type>image</type> <url>http://works.mztm.jp/kobashi/sample/image/image1.jpg</url> </file> <file> <id>img2</id> <type>image</type> <url>http://works.mztm.jp/kobashi/sample/image/image2.jpg</url> </file> <file> <id>img3</id> <type>image</type> <url>http://works.mztm.jp/kobashi/sample/image/image3.jpg</url> </file> <file> <id>img4</id> <type>image</type> <url>http://works.mztm.jp/kobashi/sample/image/image4.jpg</url> </file> </files> </data>
ゆとりを実装したソースです。
package{
import br.com.stimuli.loading.lazyloaders.LazyXMLLoader;
import br.com.stimuli.loading.lazyloaders.LazyBulkLoader;
import br.com.stimuli.loading.*;
import br.com.stimuli.loading.loadingtypes.*;
import br.com.stimuli.loading.BulkProgressEvent;
import flash.events.*;
import flash.display.*;
public class Main extends MovieClip{
public var lazy : LazyXMLLoader;
public function Main () : void {
var url:String = 'http://works.mztm.jp/kobashi/sample/xml/conf.xml';
lazy = new LazyXMLLoader(url, 'theLazyLoader');
lazy.addEventListener(LazyBulkLoader.LAZY_COMPLETE, onXmlLoaded)
lazy.addEventListener(Event.COMPLETE, onAllLoaded);
lazy.addEventListener(ProgressEvent.PROGRESS, onAllProgress);
lazy.start();
}
public function onXmlLoaded (e:Event):void {
trace('onXmlLoaded');
}
public function onAllProgress (e:BulkProgressEvent):void {
trace('onAllProgress');
}
public function onAllLoaded (e:Event):void {
trace('onAllLoaded');
var sp:Sprite;
for each (var item : LoadingItem in lazy.items) {
trace(item.id);
trace(item.type);
switch (item.type) {
case 'image' :
sp = new Sprite();
sp.addChild(lazy.getBitmap(item.id));
sp.addEventListener(MouseEvent.MOUSE_DOWN, function (e:MouseEvent):void {
var sp:Sprite = e.target as Sprite;
addChild(sp);
sp.startDrag();
});
sp.addEventListener(MouseEvent.MOUSE_UP, function (e:MouseEvent):void {
var sp:Sprite = e.target as Sprite;
addChild(sp);
sp.stopDrag();
});
addChild(sp);
break;
}
}
}
}
}


