トップページ > Flash入門 > とりあえず(4)
画像を回転させること自体は簡単で,回転させたい画像のrotationパラメータの値を変更するだけです。 ball.rotation = 1のような感じです。 アニメーションに際しては, 前ページで作ったonEnterFrame()関数の中身を,
//各フレームごとに呼ばれる関数 private function onEnterFrame(e:Event):void { //"ball"を回転させる ball.rotation += 0.5; }
という具合に変えるだけです。なお,“rotation”は画像の角度を表すパラメータですが,単位は度(degree)となっているようです。
何も考えずに,rotationパラメータをどんどん増やしていくプログラムを走らせてみます。 フレームごとのイベント処理を実装する方法は前ページと同じです。 srcディレクトリには,表示用画像(今回は"ClearBall_pink.png")を入れておく必要があります。
package { import flash.display.Bitmap; import flash.display.Sprite; import flash.events.Event; //画面サイズと背景色,フレームレートを設定 [SWF(width="300", height="300", frameRate = "60", backgroundColor="0xffffcc")] /** * ... * @author NB */ public class Main extends Sprite { //画像ファイルを読み込む [Embed(source = "./ClearBall_pink.png")] public var ballImg:Class; //"ball"をクラス変数として定義 public var ball:Bitmap = new ballImg(); //main関数 public function Main():void { if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); } //コンストラクタ private function init(e:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, init); // entry point //フレームごとの処理をイベントリスナへ登録 this.stage.addEventListener(Event.ENTER_FRAME, onEnterFrame); //ballの位置を中央付近へ動かす ball.x = 100; ball.y = 100; //"ball"を画面に表示 addChild(ball); } //各フレームごとに呼ばれる関数 private function onEnterFrame(e:Event):void { //"ball"を回転させる ball.rotation += 0.5; } } }
上記ソースコードを走らせると,次のようなFlashが再生されます。
確かに回転していますが,回転中心は画像の中心ではなく画像の原点になっています。
これはこれで応用先があると思いますが,画像の中心を軸として回転させたいところです。
Action Scriptには,画像をその中心で回転させる関数が用意されていないようです。 そこで画像をその中心で回転させる方法としては,ダミーの「スプライト」を用意して回転させる方法がよく用いられるようです。 とりあえず,理屈ぬきにどんな感じになるのか見てみます。
青い四角形の上に,回転させたい画像が乗っかる感じになっています。 この青い四角の部分がダミーのスプライトになっています。 青い四角の“子”として画像を登録(addChild)しているので,青い四角が回転すれば同時に画像も回転します。 青い四角の原点がちょうど画像の中心になるように指定すれば,画像自体はまるで中心を軸に回転しているように 見せることができます。
先の例ではダミーのスプライトを四角く塗りつぶすようなプログラムとしていましたが, これは理解しやすくするためであって,実際は色を付ける必要はありません。 上のFlashのようにダミーのスプライトの色を消せば,ただ画像が中心で回転しているように見えます。 「スプライト」というのは,画像を表示するための小さいブロックというイメージです。 スプライトは普通の画像のように位置や角度を指定することができます。 また,好きな色に塗りつぶしたり,好きな図形を描画することもできます。 画像を表示する際も,実のところ,スプライトを1つ生成してそこに画像を表示している感じになっています。 このスプライトを1つ余分に作って,画像を回転させる目的だけに使っているということです。
“//===”のコメント行で囲われた部分が新しい部分です。 srcディレクトリには,表示用画像(今回は"ClearBall_pink.png")を入れておく必要があります。
package { import flash.display.Bitmap; import flash.display.Sprite; import flash.events.Event; //画面サイズと背景色,フレームレートを設定 [SWF(width="300", height="300", frameRate = "60", backgroundColor="0xffffcc")] /** * ... * @author NB */ public class Main extends Sprite { //画像ファイルを読み込む [Embed(source = "./ClearBall_pink.png")] public var ballImg:Class; //"ball"をクラス変数として定義 public var ball:Bitmap = new ballImg(); //================================================================ //画像回転に使うダミーのスプライト,名前は"sp"とする public var sp:Sprite = new Sprite(); //================================================================ //main関数 public function Main():void { if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); } //コンストラクタ private function init(e:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, init); // entry point //フレームごとの処理をイベントリスナへ登録 this.stage.addEventListener(Event.ENTER_FRAME, onEnterFrame); //============================================================ //"sp"の座標は,"ball"を表示させたい位置+ballの中心までの距離 sp.x = 90 + ball.width / 2; sp.y = 90 + ball.height / 2; //"sp"を画面に表示 addChild(sp); //"ball"の中心が"sp"の原点になるようにする //座標の指定は親オブジェクトであるspからの相対距離 ball.x = -ball.width/2; ball.y = -ball.height / 2; //"ball"を"sp"の上へ貼りつける sp.addChild(ball); //============================================================ } //各フレームごとに呼ばれる関数 private function onEnterFrame(e:Event):void { //"sp"を回転させる(その上に貼りついている"ball"も回転する) sp.rotation += 0.5; } } }
そもそも「スプライト」というのは,昔から使われている処理上のテクニックです。 ディスプレイに画像を表示する流れは,画面用メモリ(VRAM)に一度表示画面全体の映像を保存し, グラフィックボードがそれを順次ディスプレイへ信号として吐き出す・・・という感じになっています。 (詳しくはグラフィックボードの原理参照です。) アニメーションを滑らかに動いているように見せるためには, 高速で画面描画を繰り返す必要があります。 しかし,画面全体の表示を更新していると時間がかかってしまい,アニメーションが遅くなってしまいます。 そこで,「実際に動いている部分」の画面用メモリだけを書きかえることで処理時間を減らそう・・・というのが スプライトです。
Flashでは,このスプライトを手軽に扱えるようになっているみたいです。 var sprite:Sprite = new Sprite() とスプライトのクラスをインスタンス化すれば, "sprite"という1つの変数として自由に操作できます。 Javaの場合はこれができなかったので,アニメーション表示の際はダブルバッファリングなんかをしていたのでした。。。
先の例で示した,回転用に下地として使っているSpriteが青い正方形として見えるようにした場合のソースコードです。 “//===”のコメント行で囲われた部分が新しい部分です。 srcディレクトリには,表示用画像(今回は"ClearBall_pink.png")を入れておく必要があります。
package { import flash.display.Bitmap; import flash.display.Sprite; import flash.events.Event; //画面サイズと背景色,フレームレートを設定 [SWF(width="300", height="300", frameRate = "60", backgroundColor="0xffffcc")] /** * ... * @author NB */ public class Main extends Sprite { //画像ファイルを読み込む [Embed(source = "./ClearBall_pink.png")] public var ballImg:Class; //"ball"をクラス変数として定義 public var ball:Bitmap = new ballImg(); //画像回転に使うダミーのスプライト,名前は"sp"とする public var sp:Sprite = new Sprite(); //main関数 public function Main():void { if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); } //コンストラクタ private function init(e:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, init); // entry point //フレームごとの処理をイベントリスナへ登録 this.stage.addEventListener(Event.ENTER_FRAME, onEnterFrame); //"sp"の座標は,"ball"を表示させたい位置+ballの中心までの距離 sp.x = 90 + ball.width / 2; sp.y = 90 + ball.height / 2; //"sp"を画面に表示 addChild(sp); //"ball"の中心が"sp"の原点になるようにする //座標の指定は親オブジェクトであるspからの相対距離 ball.x = -ball.width/2; ball.y = -ball.height / 2; //"ball"を"sp"の上へ貼りつける sp.addChild(ball); //============================================================ //"sp"の部分を青い矩形として塗りつぶす sp.graphics.beginFill(0x0000FF); sp.graphics.drawRect(0, 0, 120, 120); sp.graphics.endFill(); //============================================================ } //各フレームごとに呼ばれる関数 private function onEnterFrame(e:Event):void { //"sp"を回転させる(その上に貼りついているballも回転する) sp.rotation += 0.5; } } }