3. 画像ファイルの埋め込み
次に、画像ファイルを表示する方法を見ていきましょう。ActionScript 3では、外部の画像ファイルをその時々で動的に読み込んで表示することもできますが、素材となる画像ファイルをSWFファイルの中に埋め込んで表示することもできます。
ここでは、画像ファイル「panda.png」をSWFファイルに埋め込んで、これを表示してみます。
// EmbedTest package { import flash.display.*; import flash.events.*; public class EmbedTest extends Sprite { // *1 埋め込みイメージの指定 [Embed(source='panda.png')] private static const ImagePanda: Class; public function EmbedTest() { // *2 Bitmapとして生成 var bmp:Bitmap = new ImagePanda() as Bitmap; addChild(bmp); } } }
埋め込みたい画像は*1の行のようにEmbed
とソースの指定を行い、直後で埋め込んだ画像をクラスとして宣言します。宣言されたクラスを利用しているのが*2の部分です。そのクラスの型をそのまま生成しないで、Bitmap
の型を宣言します。Bitmap
を生成したら、これを表示するために、addChild()
で画面に表示します。
4. マウス操作
今度は、マウスの操作を処理する方法を見てみましょう。以下の例は、画面に赤い四角を描き、これをクリックすると右に移動するというサンプルプログラムです。
// MouseClick.as package { import flash.display.*; import flash.events.*; public class MouseClick extends Sprite { private var spriteChar:Sprite; public function MouseClick() { // sprite spriteChar = new Sprite(); spriteChar.graphics.beginFill(0xFF0000); spriteChar.graphics.drawRect(0,0,32,32); spriteChar.graphics.endFill(); addChild(spriteChar); // event spriteChar.addEventListener(MouseEvent.CLICK, onMouseClick); } private function onMouseClick(evt:MouseEvent):void { spriteChar.x += 16; } } }
マウスのクリックなど、Sprite
オブジェクトにイベントを追加する場合、オブジェクトのaddEventListener()
メソッドを使います。引数には、イベントの種類と、イベント処理を行う関数を指定します。
5. Timerの処理
続いて、ゲームを作るのに欠かせないTimer
クラスを使いましょう。Timer
クラスは一定の時間間隔で処理を行う場合に使います。ここでは、簡単なデジタル時計を例として示します。
// DClock.as package { import flash.display.*; import flash.events.*; import flash.text.*; import flash.utils.Timer; public class DClock extends Sprite { private var txtTime:TextField; private var timerClock:Timer; public function DClock() { // label txtTime = new TextField(); addChild(txtTime); // timer --- *1 timerClock = new Timer(500); timerClock.addEventListener(TimerEvent.TIMER, onTick); timerClock.start(); } private function onTick(evt:TimerEvent):void { var d:Date = new Date(); var s:String = ""; s += d.hours.toString() + ":"; s += d.minutes.toString() + ":"; s += d.seconds.toString(); txtTime.text = s; } } }
*1の部分を見ると分かると思いますが、Timer
クラスでは、生成時にタイマーの間隔をミリ秒で指定します。そして、マウスの時と同じように、addEventListener()
メソッドでイベントを処理する関数を指定し、start()
でタイマーを開始します。
6. ライフゲームの組み立て
ここまでで一通り、ライフゲームを作るために必要な知識が整理できたので、ライフゲームを組み立てていきましょう。
ライフゲームのしくみと作成手順
ライフゲームは、生命の誕生と消滅を、増殖・淘汰などのプロセスで再現したシミュレーションゲームです。碁盤のようなマス目(セル)がライフゲームの舞台となります。それぞれのセルは、生物の「生」か「死」の状態を表します。ゲームはプレイヤーが交互にプレイする「ターン制」で進み、生物の生死は、その生物の周囲の状況によって決定されます。
このゲームの根底にあるのが、生物は過疎状態でも過密状態でも生き残れないという考え方です。生死を決定するルールは次のとおりです。
- 死んでいる生物の周囲に3つの生きている生物がいれば、次のターンで生物は誕生する。
- 生きている生物の周囲に2つか3つの生きているセルがあれば次の世代でも生き残る。
- 上記以外の場合、生物は死滅する。
では、以下の手順でライフゲームを組み立てていきましょう。
- 生物クラスの作成
- クラスの定義と画像の埋め込み
- 画像の切り替え
- クリックイベントの登録
- メインクラスの作成
1. 生物クラスの作成
プログラミングのはじめに、生物を表すCreature
クラスを作ります。「生」と「死」の2つの状態を切り替えて表示できる機能を持たせることにしましょう。また、マウスでクリックすると生死の状態が反転するようにします。
2. クラスの定義と画像の埋め込み
Creature
クラスなので、「Creature.as」というファイルを作り、この中にクラス定義を書いていきます。まずクラスの定義を作り、その中に生死の状態を表す画像ファイルを埋め込むようにします。
// Creature.as package { import flash.display.*; import flash.events.*; public class Creature extends Sprite { // 埋め込みイメージの指定 [Embed(source='dead.png')] private static const ImageDead:Class; [Embed(source='live.png')] private static const ImageLive:Class; } }
3. 画像の切り替え
続いてメソッドを呼ぶことで、生死の状態を切り替えられるように、setLive()
とsetDead()
というメソッドを作ります。
// 表示中のBitmapを管理する変数 private var cur_bmp:Bitmap = null; private function removeBmp():void { if (cur_bmp != null) removeChild(cur_bmp); // *1 } private function changeImage(bmpClass:Class):void { removeBmp(); cur_bmp = new bmpClass as Bitmap; // *2 addChild(cur_bmp); isLive = (bmpClass == ImageDead) ? false : true; } public function setLive():void { changeImage(ImageLive); } public function setDead():void { changeImage(ImageDead); }
先ほど、画像を表示するためにaddChild()
を使いましたが、画像を消す場合には、プログラム中の*1の行のようにremoveChild()
を使います。つまり、画像を切り替える場合には、一度表示していた画像をremoveChild()
で消してから、新しい画像をaddChild()
します。
そして、注目したいのが*2の部分で、引数として渡された画像を表すClass
型の変数を利用して新しいオブジェクトを作成しています。
4. クリックイベントの登録
次に、クリックしたら、生死を切り替えるようにマウスイベントを登録します。
private var isLive:Boolean = false; public function Creature() { setDead(); addEventListener(MouseEvent.CLICK, onClick); } private function onClick(evt:MouseEvent):void { (isLive) ? setDead() : setLive(); }
これでCreature
クラスは完成です。
5. メインクラスの作成
メインクラスでは、先ほど作ったCreature
クラスのオブジェクトを碁盤のように画面に並べ、タイマーによって一定間隔で生死の判定を行わせる処理を行います。
まずは、メインクラスを定義します。メインクラスは、LifeGame
クラスなので、「LifeGame.as」というファイルを作りました。
以下は、クラスのコンストラクタの中で生物クラスを画面に並べる処理です。
package { import flash.display.*; import flash.events.*; import flash.text.*; import flash.utils.Timer; public class LifeGame extends Sprite { private var map:Array; private const MAX_ROWS:int = 20; private const MAX_COLS:int = 32; public function LifeGame() { // Creatureを並べる map = new Array(); for (var i:int = 0; i < (MAX_ROWS * MAX_COLS); i++) { var x:int = i % MAX_COLS; var y:int = i / MAX_COLS; var p:Creature = new Creature(); map[i] = p; p.x = x * p.width; p.y = y * p.height + 30; if (Math.random() > 0.7) p.setLive(); addChild(p); } } } }
Creature
クラスのオブジェクトを生成したら、表示する座標を計算し、後からオブジェクトを操作できるように、配列変数map
に格納します。
後は、タイマーで一定間隔ごとに世代交代の処理を行うようにすれば完成です。
public function LifeGame() { // ...省略... // タイマーの設定 ns_timer = new Timer(300); ns_timer.addEventListener(TimerEvent.TIMER, onTick); } private function onTick(eve:Event):void { // 世代交代の処理 }
完成したライフゲームの画面です。
まとめ
少し駆け足でしたが、Free Flex 2 SDKを用いたActionScript 3のプログラミングを見てきました。ActionScript 3になってオブジェクトの構造が変わってしまったので、以前からActionScriptを使っていた方は、少しとまどうところがあるかもしれませんが、イベントリスナーの使い方が統一されたりして、使い勝手がずいぶん改善された印象です。
他にもByteArray
など新しいクラスも追加されて、ActionScriptの利用の幅が広がりました。オンラインで見られるマニュアルがAdobeのWebサイトで公開されています。
これを眺めているだけで、この機能を利用してあんなことやこんなことができそうだと想像がふくらみます。Free Flex 2 SDKは、フリーで誰でも使えるコンパイラです。ぜひ、試してみてください。