前回に引き続き、Heroクラスのご紹介です。
今回は、Heroオブジェクトのアニメーション設定とイベントの追加です。
CitrusEngineでアニメーションの再生を行うには、AnimationSequenceというクラスを使用します。
StarlingのMovieClipクラス同様、テクスチャアトラスから各アニメーションのname属性を指定する形となります。
まずは、アニメーション用リソースの準備です。
本記事では、CitrusEngineのサンプルプログラムに含まれている以下のファイルを使用します。
・Hero.png
・Hero.xml
CitrusEngineのサンプルプログラムの取得は以下の通りです。
1.CitrusEngine公式HP内、「Examples」をクリック
2.「Citrus-Engine-Examples」をクリック
3.「Download ZIP」をクリック
ダウンロードしたファイルを解凍すると、「embed」というフォルダ配下に「 Hero.png / Hero.xml 」が有りますので、自身の環境にファイルをコピーして下さい。
それでは、AnimationSequenceの説明に入ります。
AnimationSequenceの生成は、以下のように行います。
//テクスチャアトラス生成 var texture:Texture = Texture.fromBitmap( new heroBitmap() ); var xml:XML = XML( new heroXml() ); var textureAtlas:TextureAtlas = new TextureAtlas( texture, xml ); //xmlで定義されているアニメーション名を格納した配列を生成 var animNames:Array = ["idle", "walk", "die", "jump", "hurt", "duck"]; //テクスチャアトラスからAnimationSequence生成 var animationSequence:AnimationSequence = new AnimationSequence( textureAtlas, animNames, animNames[ 0 ], 12, true );
第一引数に生成したテクスチャアトラスを指定します。
第二引数には、各アニメーション名を格納した配列を指定します。 格納するアニメーション名は、使用したいアニメーションのみで結構です。xmlファイルで定義されているもの全てを格納する必要はありません。
第三引数には、最初に再生を行うアニメーションを指定します。 ここで指定されたアニメーションが描画開始と同時に再生されます。
第四引数には、フレームレートを指定します。 デフォルトでは30FPSが設定されるため、指定がない場合は省略可能です。
第五引数には、アニメーションのループ有無の指定です。 デフォルトではfalseが設定されるため、ループを有効にする場合にはtrueを指定します。
AnimationSequenceの生成が終わったので、あとはHeroクラスのviewプロパティに指定するだけでアニメーション有りのHeroオブジェクトを生成する事が出来ます。
//テクスチャアトラス生成 var texture:Texture = Texture.fromBitmap( new heroBitmap() ); 〜省略〜 //AnimationSequenceをviewに設定したHeroオブジェクトの生成 var hero:Hero = new Hero("hero", { width : animationSequence.width, height : animationSequence.height, x : stage.stageWidth * 0.5, y : stage.stageHeight - 90, view : animationSequence }); add( hero );
Heroクラスは、自身の状態を判断して自動的にアニメーションの切り替えを行います。
しかし、先ほど使用したxmlファイルに定義されているアニメーション名のみに対応しているため、自前でリソースを用意する場合は、アニメーション名を合わせる必要がありますのでご注意ください。
次は、イベントの追加です。
Heroクラスは、「攻撃時」「被弾時」「ジャンプ時」にそれぞれイベントを設定する事が出来ます。
//攻撃時のイベント登録 //攻撃時用のシグナルインスタンスを生成 var signal1:Signal = new Signal(); //シグナルにコールバック関数を登録 signal1.add( giveDamageEvent ); //生成したシグナルを攻撃時のイベントとして設定 hero.onGiveDamage = signal1; //ダメージを与えたときの処理 function giveDamageEvent():void { trace( "攻撃!" ); } /** * 被弾、ジャンプ時のシグナル設定 */ //被弾 hero.onTakeDamage = 被弾用シグナルインスタンス; //ジャンプ hero.onJump = ジャンプ用シグナルインスタンス;
簡単なご紹介となりましたが、以上で本記事は終了となります。
最後まで御覧いただきありがとうございました。
追加したシグナルの動作がわかりやすいよう、Enemyオブジェクトを配置したサンプルを作成しました。
<CitrusTest.as>
package { //Starling及び、Box2Dのインポート import citrus.core.starling.StarlingState; import citrus.physics.box2d.Box2D; import citrus.objects.platformer.box2d.Crate; import citrus.objects.platformer.box2d.Enemy; import citrus.objects.platformer.box2d.Hero; import citrus.objects.platformer.box2d.MovingPlatform; import citrus.objects.platformer.box2d.Platform; import citrus.view.starlingview.AnimationSequence; import citrus.objects.Box2DPhysicsObject; import org.osflash.signals.Signal; import starling.display.Quad; import starling.textures.Texture; import starling.textures.TextureAtlas; import starling.events.Event; //StarlingStateを継承する public class CitrusTest extends StarlingState { [Embed(source="../../../assets/Hero.png")] private var heroBitmap:Class; [Embed(source="../../../assets/Hero.xml", mimeType="application/octet-stream")] private var heroXml:Class; private var timeCount : uint = 0; //コンストラクタ public function CitrusTest() { super(); } //初期化処理のところで色々と配置する override public function initialize():void { super.initialize(); //Box2d空間の作成 var box2D:Box2D = new Box2D("box2d"); add(box2D); //地面作成 var ground:Platform = new Platform( "ground", { width:stage.stageWidth, height:10, x:stage.stageWidth * 0.5, y:stage.stageHeight - 5 } ); add( ground ); //左壁作成 var leftWall:Platform = new Platform( "leftWall", { width:5, height:stage.stageHeight, x:2.5, y:stage.stageHeight * 0.5 } ); add( leftWall ); //右壁作成 var rightWall:Platform = new Platform( "rightWall", { width:5, height:stage.stageHeight, x:stage.stageWidth - 2.5, y:stage.stageHeight * 0.5 } ); add( rightWall ); //テクスチャアトラス生成 var texture:Texture = Texture.fromBitmap( new heroBitmap() ); var xml:XML = XML( new heroXml() ); var textureAtlas:TextureAtlas = new TextureAtlas( texture, xml ); //xmlで定義されているアニメーション名を格納した配列を生成 var animNames:Array = ["idle", "walk", "die", "jump", "hurt", "duck"]; //テクスチャアトラスからAnimationSequence生成 var animationSequence:AnimationSequence = new AnimationSequence( textureAtlas, animNames, animNames[ 0 ], 12, true ); //AnimationSequenceをviewに設定したHeroオブジェクトの生成 var hero:Hero = new Hero("hero", { width : animationSequence.width, height : animationSequence.height, x : stage.stageWidth * 0.5, y : stage.stageHeight - 90, view : animationSequence }); add( hero ); //ジャンプ高設定 hero.jumpHeight = 20; //攻撃時のイベント登録 var signal1:Signal = new Signal(); signal1.add( giveDamageEvent ); hero.onGiveDamage = signal1; //被弾時のイベント登録 var signal2:Signal = new Signal(); signal2.add( takeDamageEvent ); hero.onTakeDamage = signal2; //ジャンプ時のイベント登録 var signal3:Signal = new Signal(); signal3.add( jumpEvent ) hero.onJump = signal3; addEventListener( Event.ENTER_FRAME, enterFrameEvent ); } /** * ダメージを与えたときの処理 */ private function giveDamageEvent():void { trace( "攻撃!" ); } /** * ダメージを受けたときの処理 */ private function takeDamageEvent():void { trace( "被弾!" ); } /** * ジャンプしたときの処理 */ private function jumpEvent():void { trace( "ジャンプ!" ); } /** * フレームイベント */ private function enterFrameEvent():void { timeCount++; if( timeCount == 100 ){ timeCount = 0; //Enemyオブジェクトview用のオブジェクト生成 var quad:Quad = new Quad( 100, 100, 0x03C39E ); //Enemyオブジェクト生成 var enemy:Enemy = new Enemy("enemy", { width :quad.width, height :quad.height, x :stage.stageWidth * 0.1, y :stage.stageHeight * 0.1, view :quad }); add( enemy ); } } } }
<次回の更新について>
次回は、Enemyクラスについて紹介となります。
弊社では全国各地の請負い(ご自宅)で作業協力頂ける、フリーランスエンジニアの方を常時探しております。
ご興味ある方は、お気軽にお問い合わせ下さい。