今回は、前回の記事で紹介したコードをベースに、矩形を移動させてみます。利用するのは、EnterFrame イベントです。
Starling の表示オブジェクトは、Flash Player の表示オブジェクトと同じ様に、EnterFrame イベントをサポートしています。そのため、EnterFrame のイベントリスナを追加すれば、新しいフレームの表示ごとにリスナ関数が実行されます。
Starling でのイベントのしくみや、リスナの登録方法も、Flash Player の表示リストとほぼ同様です。ということで、今回紹介する方法は、既存の Flash コンテンツを再利用しやすい方法と言えそうです。
さて、今回のサンプルでは矩形を回転させたいと思います。そうすると、前回のサンプルのまま単色ベタ塗りの矩形が回転しても様子が分かりにくいでしょうから、前準備として、矩形の塗りをグラデーションに変えたいと思います。
都合のよいことに Quad クラスは、Stage3D らしく、頂点ごとに色を指定する機能を持っています。メソッドの名前は setVertexColor() です。
setVertexColor() の最初の引数は頂点の番号です。番号は、0 から順に、左上、右上、左下、右下の頂点を指します。2 つ目の引数は色の指定です。
// myQuad.color = 0xABCDEF; の代わりに以下を記述 myQuad.setVertexColor(0, 0x000000); myQuad.setVertexColor(1, 0xFF0000); myQuad.setVertexColor(2, 0x00FF00); myQuad.setVertexColor(3, 0x0000FF);
以上の指定をすれば、あとは、自動的に各頂点間のピクセルの色が補完されるため、矩形の色がグラデーションになります。
EnterFrame イベントリスナの利用
さて、本題に戻って、EnterFrame イベントリスナの追加方法です。
使用する Event クラスが Starling フレームワークに含まれるクラスである点には注意が必要ですが、今までに AS3 でイベント処理のコードを実装したことがあれば、特に違和感無く使えると思います。 (リスナ関数の削除のタイミングが少し異なります:後述)
下は、EnterFrame イベントを使って、フレームごとに矩形を回転させるサンプルコードです。前回のサンプル内の onAddedToStage() を修正したものです。
private function onAddedToStage(e:Event):void { // Quadのインスタンスを生成 myQuad = new Quad(200, 200); // 各頂点の色を指定 myQuad.setVertexColor(0, 0x000000); myQuad.setVertexColor(1, 0xFF0000); myQuad.setVertexColor(2, 0x00FF00); myQuad.setVertexColor(3, 0x0000FF); // Quadのインスタンスを中央に表示 myQuad.x = stage.stageWidth - myQuad.width >> 1; myQuad.y = stage.stageHeight - myQuad.height >> 1; // SpriteにQuadのインスタンスを追加 addChild(myQuad); // EnterFrameイベントリスナの追加 myQuad.addEventListener(Event.ENTER_FRAME, onEnterFrame); } private function onEnterFrame(e:Event):void { // Quadのインスタンスを回転させる (e.currentTarget as Quad).rotation += .01; }
フレームごとに rotation の値を大きくしているため、上のコードを実行すると、矩形が時計回りに回転します。その際、回転の基準は、矩形の左上角になっていると思います。
Starling の表示オブジェクトには、基準点を指定するための属性 pivotX と pivotY が用意されています。これらを利用すると、矩形内の任意の点を基準に回転させることができます。
pivotX と pivotY の初期値はどちらも 0 です。つまり、表示オブジェクトのデフォルトの基準点は左上の角です。
ここでは、基準点を矩形の中心に変更してみます。下は、そのサンプルです。
// 基準点をQuadインスタンスの中心に設定 myQuad.pivotX = myQuad.width >> 1; myQuad.pivotY = myQuad.height >> 1;
このように基準点を変更すると、表示位置の基準も変わりますから、その分表示位置がずれます。今回の例であれば、矩形の幅と高さの半分である 100 ピクセルずつ左と上に移動します。
そこで、位置の指定のコードを、基準点がずれた分、修正します。下が新しいコードです。
// Quadのインスタンスを中央に表示 myQuad.x = (stage.stageWidth - myQuad.width >> 1) + myQuad.pivotX; myQuad.y = (stage.stageHeight - myQuad.height >> 1) + myQuad.pivotY;
良く考えると、myQuad.pivotX = myQuad.width >> 1 なので、これは下のように書き換えられそうです。
// Quadのインスタンスを中央に表示 myQuad.x = stage.stageWidth >> 1; myQuad.y = stage.stageHeight >> 1;
以上で、画面の中央に位置する矩形が、図形の中心を基準点として回転するようになったでしょうか?
リソースの開放
Starling の表示オブジェクトには dispose() というメソッドがあります。これは、表示オブジェクトが破棄されるタイミングで呼ばれる、表示オブジェクト内で使用したリソースを開放するためのメソッドです。
Starling で表示オブジェクトのサブクラスを定義するときは、この dispose() の記述を忘れないようにします。さもないと、メモリリークの原因になってしまうかもしれません。
下は、今回のサンプルコード用の dispose() の例です。
public override function dispose():void { removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage); myQuad.removeEventListener(Event.ENTER_FRAME, onEnterFrame); super.dispose(); }
サンプルを見ての通り、ここでの主な作業は、イベントリスナの削除です。Starling のイベントリスナには弱い参照が使えないので、このタイミングで確実に削除するようにします。
メソッドの最後の行で、super.dispose() を呼び出していますが、これにより、このオブジェクトに addChild() で追加された子オブジェクト全てに対して dispose() が呼ばれます。そのため、myQuad.dispose() は明示的に記述する必要がありません。
その他の、表示リストに追加されていない表示オブジェクトがあれば、dispose() の記述は必須になります。
また、表示リストに追加できないオブジェクトで、リソースの開放が必要なオブジェクトがあれば、ここに必要な処理を記述します。
例えば、仮に、もし、他のオブジェクトと共有しない専用のテクスチャ (ここでは myTexure とします) を参照していたならば、このオブジェクトが消滅すると myTexure テクスチャも不要になります。そのため、myTexure.dispose() を記述して、myTexure が保持するビットマップ用のメモリが開放されるようにします。
次回は、矩形を動かす方法その 2 をご紹介する予定です。
コメントする