いろいろ開発をしていて、EventListenerに引数を渡せると便利だということが多々ある。とっても良くあるので、ここにメモを残しておく。

これができると、大量のオブジェクトを扱う時、いちいち e.target.name で名前をとって、対応するIDを算出して...とかする必要がなくなる。便利君である。

 

btn1.addEventListener( MouseEvent.MOUSE_OVER, onMouseOver(1));
btn1.addEventListener( MouseEvent.MOUSE_OUT, onMouseOut(1));
btn1.addEventListener( MouseEvent.CLICK, onMouseClick(1) );

btn2.addEventListener( MouseEvent.MOUSE_OVER, onMouseOver(2));
btn2.addEventListener( MouseEvent.MOUSE_OUT, onMouseOut(2));
btn2.addEventListener( MouseEvent.CLICK, onMouseClick(2) );


function onMouseOver(id:int) { 
    return function (e:MouseEvent):void{
        trace("over  : "+id);
    };

function onMouseOut(id:int) { 
    return function (e:MouseEvent):void{
        trace("out   : "+id);
    };

function onMouseClick(id:int) { 
    return function (e:MouseEvent):void{
        trace("click : "+id);
    };
}

 

 

久しぶりにPHPプログラムを書いてみて、改めてActionScriptとの違いに勘が戻るまで時間がかかってしまった。
つまらないことに時間を割かないよう、今回はPHPとActionScriptのお作法の違いを残しておこうと思うと思う。


まずは変数定義として、配列を例に掲載。
PHP

 $item_list = Array("バナナ","みかん","りんご","いちご");
 $cost_list = Array(80,50,120,90);
 $object = Array();

AS3.0

 $item_list = Array("バナナ","みかん","りんご","いちご");
 $cost_list = Array(80,50,120,90);
 $object = Array();

PHPの場合、変数定義に$を付ける。久しぶりに書いたからどうしても忘れてしまう。
あとはnewを付けるとかってところが違うだけ。("var"はPHPでも使うし)


続いて、for文と、配列への要素の追加
PHP

 for( $i = 0 ; $i < count($item_list) ; $i++ ){
  $tmpArray["item"] = $item_list[$i];
  $tmpArray["cost"] = $cost_list[$i];
  array_push( $object, $tmpArray );
 }

AS3.0

  for( var i = 0 ; i < item_list.length ; i++ ){
  var tmpArray = new Array();
  tmpArray["item"] = item_list[i];
  tmpArray["cost"] = cost_list[i];
  object.push( tmpArray );
 }

配列の要素数を数える方法が、PHPではcount(Array)で、ASではArray.lengthという違いがある。
配列への要素の追加方法はASの方が直感的で好き。

 

で、多次元配列になっている連想配列のソート方法はというと・・・
PHP

usort($object, create_function('$a,$b', 'return($a[\'cost\'] - $b[\'cost\']);'));

AS3.0

 object.sortOn("cost",Array.NUMERIC);

PHPの場合、usortというユーザー定義の比較関数を使ってソートするのだ。使い方がちょっと難しいのが難点。
それに比べ、ASではsortOn()で指定してあげるだけ。便利。

 

最後に、連想配列の時の要素の取り出し方。
PHP

 foreach($object as $key => $row){
  print($row["item"]." : ".$row["cost"]."\n");
 }

AS3.0

 その1
 for( var key in object ){
  trace(object[key]["item"]+" : "+object[key]["cost"]);
 }
 その2
 for each( var obj in object ){
  trace(obj["item"]+" : "+obj["cost"]);
 }

なるほど。
AS3で"for each"が追加されたそうなのだが、これだとキーが取り出せないんだよね。
それを考えると、この"for each"は用途が限定されてしまう。(その分、処理が早いのか?)
その点、PHPはキーも、それに対応するオブジェクトもいっぺんに取得できるのでよい。


そんな感じで、違いを残しつつソート部分は完全にメモ。

BetweenAS3の便利な機能として、イベント処理を利用することができる。

主にCOMPLETEイベントくしか使ったことはないのだが、PLAY,STOP,UPDATEと合わせて4種類が準備されているようだ。

使い方は簡単。対象のtweenに対して、addEventListener(TweenEvent.COMPLETE, 終了時の関数);  として設定するだけ。

import org.libspark.betweenas3.events.TweenEvent;   // 宣言に追加する必要あり

==============

var serialTween1:ITween = BetweenAS3.tween( mcA, { x:150 },{x:20,y:112}, 0.25);
var serialTween2:ITween = BetweenAS3.tween( mcA, { y:60 }, null, 0.15);
var serialTween3:ITween = BetweenAS3.tween( mcA, { x:200 },null, 0.2);

var tween = BetweenAS3.serial(serialTween1,serialTween2,serialTween3);

tween.addEventListener(TweenEvent.COMPLETE, endTween);

tween.play();


function endTween(){
    /*終了時の処理を書く*/
}

使い道としては色々あると思うけど、自分の場合、動いているときはボタン処理をさせたくないので、処理の開始前にボタンを利用できなく(removeEventListenerとか)して、tween完了時に再度、利用できるように(addEventListener)するといった具合に使っています。

前回のトゥイーン系ライブラリ BetweenAS3 (その2)で利用したサンプルでも、ボタンを連打できないように処理を入れています。




関連記事
ActionScript3.0  トゥイーン系ライブラリ BetweenAS3 (その1)
ActionScript3.0  トゥイーン系ライブラリ BetweenAS3 (その2)
BetweenAS3を使っていて、悩んだことがあったのでソースを調べてみた。

悩んだ内容は、逐次処理(シリアル)、並行処理(パラレル)を実行するときに、不特定の数を動作させたい時、そのトゥイーンを配列で渡せないかということ。

前回紹介したBetweemAS3の使い方では、シリアル、パラレル共に、その詳細のトゥイーンを引数につなげて設定して動かします。

// 順番に動かす場合はこんな感じ
var serialTween1:ITween = BetweenAS3.tween( mc2, { x:150 },{x:20,y:112}, 0.25);
var serialTween2:ITween = BetweenAS3.tween( mc2, { y:60 }, null, 0.15);
var serialTween3:ITween = BetweenAS3.tween( mc2, { x:200 },null, 0.2);

BetweenAS3.serial(serialTween1,serialTween2,serialTween3).play();

数も少なく、順番に動かす場合には、この方が直感的でわかりやすいと思います。
しかし、もっとシステマチックに動かさなければならない時は、これだと対処しきれないでしょう。

でも、BetweenAS3にはその対処法があったのです。素晴らしい!!

// シリアルはこれ
BetweenAS3.BetweenAS3.serialTweens( 配列 );

//パラレルはこれ
BetweenAS3.BetweenAS3.parallelTweens( 配列 );

簡単なサンプルは以下の通り
  // 動かすMovieClipを配列に保持
  var pointMcArray:Array; = [mc1,mc2,mc3,mc4,mc5,mc6];
  // 動作するtweenを保持する配列を定義
  var tweenArray = new Array();

  // for文でtweenを指定
  for(var i=0;i< pointMcArray.length ;i++){
    var tmpPointMc = pointMcArray[i];
    // tweenを定義
    var tmpTween:ITween = BetweenAS3.tween( tmpPointMc,
               { x:targetArray[i]["x"], y:targetArray[i]["y"] },
                null, 0.8, Cubic.easeOut);
    // tweenを配列に保持
    tweenArray.push(tmpTween);
  }

  // 配列を引数にtweenを設定(これはシリアル)
  var tween = BetweenAS3.serialTweens(tweenArray);
  tween.play();

下のサンプルFlashでは、Serial、Parallelボタンを押すと、ポッチがランダムな位置に(シリアル、パラレルで)移動します。
 

ごちゃごちゃした動きがある場合には、tweenを1つずつ指定するよりも、配列で指定した方が見やすいですね。


関連記事
ActionScript3.0  トゥイーン系ライブラリ BetweenAS3 (その1)
ActionScript3.0  トゥイーン系ライブラリ BetweenAS3 (その3)


動きのあるFlashを作成する場合、AS2の頃はFuse Kitを使っていたのだが、AS3になってからは BetweenAS3を利用するようになった。
使い勝手はFuse Kitなどとほとんど変わらないので違和感もないし、かなりいい感じなのでとても好きである。
開発中のアルファ版とのことだが、自分のレベルでは十分すぎる完成度。


で、使い方は以下の通り。

import org.libspark.betweenas3.BetweenAS3;
import org.libspark.betweenas3.tweens.ITween;
import org.libspark.betweenas3.easing.*

// 一番簡単なトゥイーンの方法。
BetweenAS3.tween( mc1, { x:370 },{x:20}, 0.8).play();

// 順番に動かす場合はこんな感じ
var serialTween1:ITween = BetweenAS3.tween( mc2, { x:150 },{x:20,y:112}, 0.25);
var serialTween2:ITween = BetweenAS3.tween( mc2, { y:60 }, null, 0.15);
var serialTween3:ITween = BetweenAS3.tween( mc2, { x:200 },null, 0.2);
var serialTween4:ITween = BetweenAS3.tween( mc2, { y:112 },null, 0.15);
var serialTween5:ITween = BetweenAS3.tween( mc2, { x:370 },null, 0.3);
BetweenAS3.serial(serialTween1,serialTween2,serialTween3,serialTween4, serialTween5).play();

// 並行処理の場合はこんな感じ
var parallelTween1:ITween = BetweenAS3.tween( mc3, { x:370 },{x:20}, 0.8,
Back.easeInOut);
var parallelTween2:ITween = BetweenAS3.tween( mc4, { x:370 },{x:20}, 0.8, Quint.easeInOut);
BetweenAS3.parallel(parallelTween1,parallelTween2).play();



考え方もシンプルで好きかも。


イージングの種類も多岐に渡っている。
水玉製作所さんでは、イージングのチャートシートを公開していて、これがかなり便利だったりする。
BetweenAS3 Transition cheat sheet



関連記事
ActionScript3.0  トゥイーン系ライブラリ BetweenAS3 (その2)
ActionScript3.0  トゥイーン系ライブラリ BetweenAS3 (その3)

2つの透明部分を含む画像をそれぞれMovieClip化し、マウスイベントで何らかの処理をしたい。

とっても簡単なことなのだが、ここにちょっとした問題が潜んでいた。


画像が重なりあった時、下のMCをクリックしたいのに、上にあるMCの透明部分が邪魔でクリックできないのだ。
オブジェクトを動かしている場合、画像が重なりあうのは必至。
これって結構迷惑な話である。

その対応として、mc.mouseEnabled = false; を利用してみる。

ただし、そう単純な話ではない。
上のMCにこれを設定してしまうと、上のMCをクリックしたつもりでも、下のMCをクリックしてしまう。そう、透明部分を無効にするのではなく、MC自体のマウスイベントを無効にするのだ。(あたりまえだけど)

なので、MCの構造自体を全くの別物に変えてあげる必要がある。


準備するものとしては、透明画像:Aの他に、Aを「ビットマップのトレース」したもの:B。
それらを以下のようなレイヤーでMovieClip化する。
 注:Aに半透明な部分が含まれる場合は、Bのアルファを0にしておく必要がある。

  targetMc
  ├ pngMc
  | └ 透明画像:A
  └ bitmapMc
    └ 「ビットマップのトレース」をしたもの:B

で、ActionScriptでは以下のように指定する。

targetMc.mouseEnabled = false;
targetMc.pngMc.mouseEnabled = false;

targetMc.bitmapMc.addEventListener( MouseEvent.MOUSE_UP, onClick );

function onClick(e){
  trace("targetMc Clicked");
}


解る人には当たり前の話だが、実際にクリックされているのは、bitmapMcなわけで、実際の画像はマウス操作ができない状態で表示されているだけ。
合わせて targetMcを mouseEnabled = false することで、bitmapMc のみをクリックのターゲットとする。

ちなみに、カーソルを指にする buttonMode = true; の指定については、targetMc でも targetMc.bitmapMc でも同じ結果になるようだ。(個人的には、addEventListener するターゲットと同じにした方が分かりやすいと思う)


また、単純に透明画像を含むMCが重なりあっていて、下のMCだけクリックしたいが、絵が重なっているところはクリックさせたくない場合にも使えるはず。
加えてハマった内容としては、そのMC達をそれぞれのラッパー用のMCに含んでしまっている場合。当然のごとく、上位のMCにも .mouseEnabled = false; を指定してあげないと上手くいかないので注意が必要。
 
余談だが、修正対応で各オブジェクトに.mouseEnabled = false;を入れたのだが上手くいかず。それぞれのオブジェクトをラッパー用のMCにaddChildしていたのを忘れていたため、どうしても透明部分が解消されずハマってしまった昨日・・・。
ASにはSleep関数が存在しないため、タイマーによる疑似的なスリープを設定する必要がある。


var timer:Timer = new Timer(1000 ,1); // 1000ミリ秒 = 1秒
timer.addEventListener(TimerEvent.TIMER, timerFunc);
timer.addEventListener(TimerEvent.TIMER_COMPLETE, timerCompFunc);
timer.start();

function timerFunc(Event){
    trace("予定する繰り返し回数:"+timer.repeatCount);
    trace("現在の繰り返し回数 :"+timer.currentCount);
}

function timerCompFunc(Event){
    trace("タイマーが完了");
}


1回だけ動かす場合(Sleepとして使う場合も)、TIMER、TIMER_COMPLETE のどちらを使っても同じ結果になる。
まぁ、1回だけならTIMERでやっちゃうかな。

repeatCount、currentCountプロパティを使うことで、繰り返し全体の何回目かを取得することができる。
これによって、偶数、奇数の場合で処理を分けたりもできるようだ。

注意点としては、タイマーに指定した処理間隔にズレが生じる場合があるらしい。
これは、呼び出された関数で処理が完了してからの間隔であるため、関数内で時間がかかると、その分、次の処理に遅れが出るとのこと。
 # どこかの記事で読んだだけで、自分は未確認・・・。
最近AS3に染まりきっている感じ。
それでも物覚えが悪いので、毎回同じようなことをGoogleさんに聞いて回っているので効率もいまいち。

という訳で、まずは簡単な文字列操作を覚書。

まずは、変数定義。

var targetStr:String ;
var targetStr1:String ;
var targetStr2:String ;
var pattern:RegExp;
var resultObject:Object;

最初に、邪魔な文字列を削除する場合。

ずっと1つ目のやり方でやっていたのだけど、replace関数があることを発見!!(←遅いよ・・・)
入れ替えだけならかなり便利だ。


// "target006SubMc" の "Sub" を削除して "target006Mc" としたい場合(その1)
targetStr = "target006SubMc";
targetStr1 = targetStr.split("Sub").join("");

trace(targetStr,targetStr1); // →出力結果: target006SubMc target006Mc

// "target006SubMc" の "Sub" を削除して "target006Mc" としたい場合(その2)
targetStr = "target006SubMc";
targetStr1 = targetStr.replace("Sub","");

trace(targetStr,targetStr1); // →出力結果: target006SubMc target006Mc


続いて、文字列の中の一部を取り出す方法。

「その2」は正規表現を利用してみたが、数字が含まれない場合は戻り値がないからエラー処理も必要になるはず。
どちらがよいのかは不明。


// "target006Mc" の "006" だけ取り出したい(その1)
targetStr = "target006Mc";
targetStr1 = targetStr.substr("target".length);
targetStr2 = targetStr1.substr(0,targetStr1.indexOf("Mc")) ;

trace(targetStr,targetStr1,targetStr2); // →出力結果: target006Mc 006Mc 006


// "target006Mc" の "006" だけ取り出したい(その2)
// AS3.0から正規表現が使えるようになった!!
targetStr = "target006Mc";
pattern = /(d+)/;
resultObject = pattern.exec(targetStr);

trace(targetStr,resultObject[0]); // →出力結果: target006Mc 006


AS3.0から正規表現が使えるようになったことは、かなり使えると思う。
でも、PerlとかPHPとかとちょっとお作法が違うので戸惑ってます。
まぁ、使えることには間違いない。


で、もうひとつおまけで、正規表現を使った数字の金額へ補正するプログラム。



// 正規表現を使って、数字を金額用のカンマ付きの文字列として返す
var price:int = 10000000; // 1千万
trace(getPriceString( price )); // →出力結果: 10,000,000


function getPriceString( price ){
var pattern:RegExp = /(d)(?=(d{3})+(?!d))/g;
return String(price).replace(pattern, "$1,");
}


とりあえずこの位は押さえておきたい・・・。


2011年4月

          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

最近のコメント

アイテム

  • screenshot_1.png
  • screenshot_2.png
  • mzl.jpqumane.480x480-75.jpg
Powered by Movable Type 5.02