page_adsence

ラベル ActionScript3 の投稿を表示しています。 すべての投稿を表示
ラベル ActionScript3 の投稿を表示しています。 すべての投稿を表示

2010年7月7日水曜日

タイムライン上にActionScript書いたらコンパイルエラーになった

初めてタイムライン上にASを書いてみた。
そしたらコンパイルエラー・・・。

「1180: 未定義である可能性が高いメソッド addFrameScript の呼び出しです。」

なんじゃこりゃ。
コメントだけ入れてみてもエラーのまま。
何が原因なんだろうと思って調べてみたら、ドキュメントクラスはSpriteで定義されているのにも関わらず、
stageがMovieClipになっていることが原因みたいです。

自分なりに噛み砕くとドキュメントクラスはSprite(タイムラインを持たない)で定義してあるのに、
Flash IDE上のタイムラインにソースがあるのはおかしいってことみたいです。

なので、対応方法は2つ。
1つめはドキュメントクラスをSpriteからMovieClipに変更する。

例)ドキュメントクラスがMainだった場合
public class Main extends Sprite

public class Main extends MovieClip

2つめはタイムライン上のスクリプトを削除する。
削除というのはコメントアウトということではなく、
タイムライン上に記述されているスクリプト全てを消すことである。

一応この2通りの対応方法がある。

2010年7月6日火曜日

dispatchEventに任意のパラメータを渡す

dispatchEventにパラメータを渡したい場合は自分で拡張するしかないらしい。
FlexSDKには元々mx.events.DynamicEventというものがあるみたいで、それを使えば出来るらしい。
なので、それを元にASのコードを書いてあげればOKみたいです。
ただし、受信側と送信側のどちらにパラメータをつけたいかで実装が変わるようです。
これがDynamicEventクラスの実装。
package {
import flash.events.Event;

public dynamic class DynamicEvent extends Event {
public function DynamicEvent(type:String, bubbles:Boolean = false,cancelable:Boolean = false) {
super(type, bubbles, cancelable);
}

override public function clone():Event {
return new DynamicEvent(type, bubbles, cancelable);
}
}
}


dynamicクラスになっている理由はコンパイルエラーを回避するためらしい。
現在は未検証。

送信側でパラメータを渡したい場合は以下の通り
var event:DynamicEvent = new DynamicEvent("eventName");
event.param1 = "文字列";
event.param2 = [1, 2, 3]; // 配列もOK
dispatchEvent(event);


受信側の設定は以下の通り
// イベントリスナーの設定
addEventListener("eventName", callbackFunction );

// コールバック側
private function callbackFunction(event:DynamicEvent):void {
trace(event.param1);
}


受信側でパラメータを渡したい場合は以下の通り
package {
import flash.display.Sprite;
import flash.events.Event;

public class MyClass extends Sprite {
// constructor
public function MyClass() {
var counter:int = 0;
//addEventListener()の第二引数をクロージャとして渡している
stage.addEventListener("click", function(event:Event):void {
clickHandler(event, counter++);
});
}

// コールバックメソッド
private function clickHandler(e:Event, counter:int):void {
trace( e.type + ':' + counter );
}
}
}


参照元:http://blogs.yahoo.co.jp/k3_labs/4399737.html

2010年7月5日月曜日

AS3のfor文で次の繰り返しに行く

AS3のfor文で次の繰り返しへいきたい場合は「continue」を使う。
JavaScriptと同じだけど、最近はJqueryばかり使っていたので「return false」とか書いてしまった・・・。
一応メモ。

var b = [1,2,3,4,5,6,7,8,9,10];
for ( var a in b ) {
if ( a > 5 ) continue;
trace(a);
}
// 出力
1
2
3
4
5

2010年7月2日金曜日

AS3でswf自身のパスを取得する

swf自身が設置されているパスを取得するには以下の通り。
ドキュメントクラスの場合は
root.loaderInfo.url;

で取得することが可能。

2010年6月29日火曜日

マスクをかける

画像の端をぼやっとした感じにするためにはマスクとやらをかければいいらしい。
画像の編集とかしたことないからとりあえず用語の意味から調べてみた自分なりの見解。

「マスク」はマスキングテープなどで使われている「マスク」と同義で、
「マスク」とは保護するといった意味がある。

なるほど。
たしかに、昔プラモデルを作る際にマスキングテープを実際使っていたが、
色の境目になる部分にマスキングテープを貼り、先に塗ってある色を保護した状態で、
新しい色を上塗りすることで、綺麗に色の境目を表現することができるようになる。

Flashなどではこのマスキングテープを色々加工できて、
マスキングテープを加工することで保護しているレイヤーを加工しなくても
同様の効果が得られるようになっているって感じだと思われる。

今回はASを使ってマスクをかけてみた。
といってもできることはFlashの方で作業しておく。

手順1

まずマスクをかけたいレイヤーの上にマスク用のレイヤーを追加する。

手順2

追加したレイヤーにマスク用のシンボルを作成する。
このシンボルはどういったマスクをかけるかによって、形や効果の設定を変える必要がある。
今回は画像全体を角丸っぽくしつつ、画面四隅にぼかしを入れる。
なので矩形プリミティブツールを選択してステージ全体よりちょっと小さめに四角を配置する。
矩形オプションで角丸具合を調整してムービープリップシンボル化し、インスタンス名(今回はmask_mcとする)をつける。

手順3

手順2で追加したmask_mcに対してプロパティパネルの下にあるフィルタプロパティにぼかしを追加する。
ぼかしXとぼかしYは任意で調整する。
また表示のブレンドを標準にし、ビットマップとしてキャッシュにチェックをつける。

手順4

マスクをかけたいレイヤーを選択し、そこにあるムービークリップ(main_mc)に対してもプロパティパネルの表示のブレンドを標準にし、ビットマップとしてキャッシュにチェックをつける。

※注意
グラデーションマスクをかける場合は必ずマスクをかける側とかけられる側の両方にビットマップとしてキャッシュの部分にチェックをつける必要がある。

手順5

ASでMovieClipに対してマスクをかける処理を追加する。

main_mc.mask = mask_mc;

以上でグラデーションマスクをかけることができる。
なお、ビットマップとしてキャッシュにチェックをつける代わりに、
AS側で

main_mc.cacheAsBitmap = true;
mask_mc.cacheAsBitmap = true;

としても実現することが可能。

2010年6月28日月曜日

AS3でのxmlの扱い

読み込んだXMLの各ノードやテキストへのアクセス方法。

読み込んだXMLファイルは以下

<?xml version="1.0" encoding="UTF-8"?>
<imageList>
<image display="show">
<main><![CDATA[./img/main1.jpg]]></main>
<thumnail><![CDATA[./img/thumnail1.jpg]]></thumnail>
</image>
<image display="show">
<main><![CDATA[./img/main2.jpg]]></main>
<thumnail><![CDATA[./img/thumnail2.jpg]]></thumnail>
</image>
<image display="hide">
<main><![CDATA[./img/main3.jpg]]></main>
<thumnail><![CDATA[./img/thumnail3.jpg]]></thumnail>
</image>
<image>
<main><![CDATA[./img/main4.jpg]]></main>
<thumnail><![CDATA[./img/thumnail4.jpg]]></thumnail>
</image>
</imageList>


読み込んだXMLファイルをXMLオブジェクトに格納する

var xmlLoader:URLLoader = new URLLoader();
xmlLoader.dataFormat = URLLoaderDataFormat.TEXT;
xmlLoader.addEventListener(Event.COMPLETE, onXMLLoadHandler);

var urlReq:URLRequest = new URLRequest(url);
xmlLoader.load(urlReq);

private function onXMLLoadHandler(event:Event):void
{
var my_xml:XML;
my_xml = new XML(xmlLoader.data);
}


で、このmy_xmlに対して色々していく。
imageノードにアクセスする
trace(my_xml.image);

出力:
<image display="show">
<main><![CDATA[./img/main1.jpg]]></main>
<thumnail><![CDATA[./img/thumnail1.jpg]]></thumnail>
</image>
<image display="show">
<main><![CDATA[./img/main2.jpg]]></main>
<thumnail><![CDATA[./img/thumnail2.jpg]]></thumnail>
</image>
<image display="hide">
<main><![CDATA[./img/main3.jpg]]></main>
<thumnail><![CDATA[./img/thumnail3.jpg]]></thumnail>
</image>
<image>
<main><![CDATA[./img/main4.jpg]]></main>
<thumnail><![CDATA[./img/thumnail4.jpg]]></thumnail>
</image>


mainの中のテキストにアクセスする
trace(my_xml.image.main.text());

出力:
./img/main1.jpg./img/main2.jpg./img/main3.jpg./img/main4.jpg


imageノードのdisplay属性にアクセスする。
trace(my_xml.image.@display);

出力:
showshowhide


imageの1番目にアクセスする
trace(my_xml.image[0]);

出力:
<image display="show">
<main><![CDATA[./img/main1.jpg]]></main>
<thumnail><![CDATA[./img/thumnail1.jpg]]></thumnail>
</image>


imageのdisplay属性がshowになっているものだけにアクセスする
trace(my_xml.image.(hasOwnProperty("@display") && @display == "show"));

出力:
<image display="show">
<main><![CDATA[./img/main1.jpg]]></main>
<thumnail><![CDATA[./img/thumnail1.jpg]]></thumnail>
</image>
<image display="show">
<main><![CDATA[./img/main2.jpg]]></main>
<thumnail><![CDATA[./img/thumnail2.jpg]]></thumnail>
</image>


とりあえず今回使ったのはこんな感じ。

画像のサイズ変更

Loaderを使って画像を読み込んだ後に、画像のサイズを指定のサイズにしたい場合は以下のようにする。
ちなみに画像はStageやMovieClipに追加した後には変更できないらしい。
かといってloadの直後に実行するとまだ画像が読み込み終わってない場合もあり、確実ではない。
なのでlode完了後、addChildする前にサイズを指定する必要がある。
やり方は以下の通り。

var loder = new Loader();
loader.addEventListener(Event.COMPLETE, onLoadImg);

var request:URLRequest = new URLRequest(url);
loader.load(request);

private function onLoadImg(event:Event){
loader.height = 100;
loader.width = 100;
addChild(loader);
}

MovieClipのインスタンス名からMovieClipインスタンスを取得する

読み込んだ画像を指定のMovieClipに追加しようと思ったが、どうやってMovieClipを取得するのかわからなかったので調べた。
MovieClipのインスタンス名を記述するだけじゃMovieClipObjectは取得できないので、
getChildByNameを使う。

var mc:MovieClip = MovieClip(getChildByName('movieClipName'));
mc.addChild(loder);

パッケージ名について

FlashDevelop使っていろいろやっていたらpackageのとこに勝手にディレクトリ構造がドットシンタックスで書かれた状態で追加されていた。
なんだろうと思ってパッケージ名について調べてみた。

パッケージとは
パッケージとはクラスファイルが保存されているフォルダまでのパスのこと
パッケージは省略可能

命名規則
反転ドメイン命名規則を使う。
接頭辞(com、netなど)は小文字のみ。接頭辞以外で単語を続ける時は区切りを大文字。

だそうです。
ふむ、とりあえず誰かに公開する予定もないし、省略しておいていいかな。

2010年6月25日金曜日

外部のasファイルでドキュメントクラスを変更する場合

例)ドキュメントクラスをTestからTest2へ変更する場合

ドキュメントクラスを変更する場合は左の画像のようにクラスをTestからTest2に修正して保存する。
あと、ASファイル名をTest.asからTest2.asに変更して保存する。
これでドキュメントクラスの変更は完了。

2010年6月21日月曜日

関数の引数に初期値を与えておく

こうやるみたい。
まぁ普通だ。

function dummy(test:string='aaa', flag:Boolean=true){
code...
}

Flashの文字コード

Flashで扱える文字コードはUnicodeとShift-JISの2種類。
Unicodeと言っても標準的に使われている文字コードはUTF-8なので、
現実的にはUTF-8とShift-JISの2種類といっていいと思われる。

FlashでShift-JISを使用する場合にのみ
System.useCodePage = true;

と記述する必要がある。
デフォルトでUTF-8を使うことが想定されているので、
UTF-8を使用する場合には特にこれを意識する必要はない。

2010年6月20日日曜日

flash.display.Spriteとflash.display.MovieClipの違い

Spriteクラスは表示リストの基本的要素で、
グラフィックを表示でき、子を持つこともできる表示リストノード。
ただしSpriteオブジェクトはタイムラインを持たない。

MovieClipクラスはSprite、DisplayObjectContainer、InteractiveObject、DisplayObject、EventDispatcher の各クラスを継承している。
MovieClipオブジェクトには、Spriteオブジェクトとは違ってタイムラインがある。

まぁ最大の違いはタイムラインがあるかないかってことみたい。
タイムライン制御が入っている分、パフォーマンスが悪くなるみたいなので、
Spriteクラスで実現できなかった場合にMovieClipクラスを使うようにしよう。
よく使うと思うので覚えておくことにする。

2010年6月19日土曜日

AS3のループ処理のコストに関して

XMLファイルに書かれている内容を順番に取り出そうと思ってループ処理について調べてみた。

まず書き方。
Arrayクラスの場合(JavaScriptとかと同じ)
arrayName:Array = new Array();
arrayName:Array = [];


Vectorクラスの場合
arrayName:Vector.<typeName> = new Vector.<typeName>();


正直このVectorクラスの書き方は違和感ありまくりです。
ちょっと疑問に思ったのはVectorクラスの場合、短縮形の書き方ないのかなぁ。
調べた感じでてこなかったし、試しに[].<typeName>;って書いてみたけど見事にエラーになったから無理なのかも。ちょっと残念。

次に速度。
wonderflにベンチマークがありました。
for inとfor each inではfor each inの方が早いみたいですね。
ただしfor each inは配列のキーが取得できないので、もしキーが必要な場合は必然的にfor inを使う必要があります。

また、ArrayクラスとVectorクラスでも速度が変わってきます。
Vectorクラスは1つのデータ型のみ格納可能で、0から順に格納することしかできませんが、その分高速に動きます。
なので、優先順位としてはまずVectorクラスを、無理であればArrayクラス使うように癖をつけた方がよい。

今回のXMLファイルのロードに関してはURL:Stringを配列に突っ込むだけの処理だったので、
一番高速なVectorクラスにfor each inで値を格納してみました。
一応理論上は高速なはず。