ちょうどシーン遷移があるFlashコンテンツを作ることになったので迷わずProgressionを採用。便利さを再確認。従来の方法だと丸2日くらいかかりそうな実装が1日で完了。ただ、少しハマったところがあったのでメモ。当初こういうスクリプトを書いていました。
addCommand(
new LoaderList(
{ onProgress:function():void {
}
},
function():void {
for (var i:int = 0; i < imgList.length; i++) {
addCommand(new LoadBitmapData(new URLRequest(imgList[i])));
}
}),
function ():void {
var bmpData:BitmapData;
var bmp:Bitmap;
for (var i:int = 0; i < imgList.length; i++) {
bmpData = getResourceById(imgList[i]).toBitmapData();
bmp = new Bitmap(bmpData);
var posX:Number = bmp.width * i;
var thumbBtn:ThumbBtn = new ThumbBtn( { bmp:bmp, x:posX, link:urlList[i]} );
insertCommand(new AddChild(_base, thumbBtn));
}
}
);
どうもbmpData = getResourceById(imgList[i]).toBitmapData();がnullになってしまってハマりました。forが処理しきる前に次のコマンドが実行されてしまっているようです。
あれこれ調べていると大重さんのProgression本にこんな記述があって無事解決。
シリアルリストの中でfunctionステートメントを実行すると内部のステートメントも順に実行されていきますが、functionステートメントの中でaddCommand()を使って追加したコマンドは実行中のシリアルリストのすべてのコマンドの最後に追加実行されます。しかしinsertCommand()でコマンドを追加するとfunctionに続いて実行するコマンドとして挿入されます。
なので上のコード内のaddCommandをinsertCommandにすることで無事解決。助かりました。
大重 美幸
ソーテック社
売り上げランキング: 19010
ロード自体は簡単なんですが、ロードした画像をマスクしたり基準点を中央にするまでは少しコードを加える必要があります。またクリッカブルにする際にはいくつか注意すべきこともあります。ロードは下記のようなコードで簡単にできます。
var obj:Sprite = new Sprite();
obj.addEventListener(MouseEvent.CLICK, _onClick);
var imgLoader:Loader = new Loader();
var urlReq:URLRequest = new URLRequest("hoge.jpg");
obj.addChild(imgLoader);
obj.mouseChildren = false;
imgLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageLoaded);
imgLoader.load(urlReq);
obj.mouseChildren = false;と書いておかないと、objの子インスタンス(この場合はimgLoader)にもaddEventListener()が有効になってしまいます。つまりe.targetがimgLoaderになってしまいます。これを防ぐためにmouseChildren = falseとしておきます。
この読み込まれた画像の基準点は左上になっています。スケールの拡大などを利用する際に基準点を中央にしたほうが何かと使い勝手がよい場合が考えられます。以下のように設定しておけば基準点を中央にすることが可能です。
/*onImageLoaded関数内*/
e.target.loader.x = -e.target.loader.width / 2;
e.target.loader.y = -e.target.loader.height / 2;
マスク(マスクの形状は正円とします)をかける際に、読み込む画像がタテだったりヨコだったりを自動的に判別させることもできます。ただ画像サイズは統一しておく必要があります。
処理内容では読み込んだ写真に内接する最大サイズの円で切り抜きます。つまり写真のヨコとタテの短いほうの辺の長さで円形に切り抜けばいいです。式で表すと下記のようになります。
_maskObj.graphics.drawCircle(0, 0, Math.min(e.target.loader.width / 2, e.target.loader.height / 2));
(続きを読む…)
ActionScript3.0で「敷居をまたぐ」if文の処理。この数値からこの数値の間に一度だけ特定の処理を実行させたい場合に使います。例えば変数nowXの値が1以下の場合に関数hogeを実行させたいとします。パッと思いつくのは下記のような式です。
if(nowX < 1) hoge();
enterframeでifを毎フレームチェックしている場合、nowXが1以下になると毎回hoge()が実行してしまうため動作が思うようになりません。「enterframeを動かしている中でnowXが1以下の場合に一回だけ実行」する場合を考えます。
まず現在のnowXより前の数値を変数(ここではpreXとします)に格納しておきます。preXを利用すれば残り1の敷居は下のようなif文で表すことができます。
if(nowX < 1){
if( preX >= 1){
hoge();
}
}
preXは次のタイミングでnowXになるので、preXが1より前で、nowXが1より後のタイミングは一度しかないので、hoge()も一度しか実行されないことになります。