[ Starling ] ボーンアニメーションの利用 2/2

前回は、DragonBonesのインストールと、ファイルの出力方法を紹介しました。
今回は、出力したファイルを使用して、ボーンアニメーションの実装について紹介します。

実装に入る前に、前回ダウンロードした「dragonbones_v2.4.1」の DragonBonesLibraryAS\bin 配下にある “DragonBones.swc” を適当な場所にコピーし、flaファイルのActionScript設定からライブラリパスの追加をして下さい。

DragonBonesでのボーンアニメーションには、DragonBonesライブラリにあるStarlingFactoryとArmatureクラスを使用します。
始めに、StarlingFactoryクラスで、アニメーションデータのパースを行います。 
前回の記事で、アニメーションのメタデータを含んだ形で画像ファイルを出力しているので、パース対象となるファイルは”Dragon.png”となります。
パースといっても、特別な処理を記載する必要はなく、出力したファイルのビットマップを引数に、StarlingFactoryクラスがもつparseDataメソッドを実行するだけです。
パース後は、StarlingFactoryクラスのbuildArmatureメソッドで、Armatureクラスのインスタンスを生成します。
Armatureクラスとは、アニメーション管理を行うためのクラスで、displayプロパティ(Sprite)で描画、animationプロパティ(MovieClip)でアニメーションに関する操作を行います。

以上が、DragonBonesのボーンアニメーション実装の基本となります。
それでは早速、実装に入ります。

まずは、単純に出力したファイルをオブジェクトとして表示するまでを行います。

        import citrus.core.starling.StarlingState;
        import dragonBones.Armature;
        import dragonBones.factorys.StarlingFactory;
        import flash.events.Event;
        import starling.display.Sprite;



        [Embed(source="./../../../res/img/Dragon.png", mimeType = "application/octet-stream")]
        private var DragonBitmap:Class;
 
        private var factory			:StarlingFactory;
        private var armature		:Armature;
        private var armatureClip	:Sprite;
		
        private var isLeft			:Boolean;
        private var isRight			:Boolean;
        private var isJumping		:Boolean;
        private var moveDir			:int=0;
        private var speedX			:Number = 0;
        private var speedY			:Number = 0;
		
        /**
		 * コンストラクタ
		 */
        public function StarlinTestMain()
        {
    		//starling専用のfactoryインスタンスを生成する()
    		factory = new StarlingFactory();
    		//イベントリスナーを登録する
    		factory.addEventListener(Event.COMPLETE, textureCompleteHandler);
    		//アニメーションデータをパースする
    		factory.parseData(new DragonBitmap());
    	}
 
		/**
		 * テクスチャ読み込み完了コールバック
		 */
        private function textureCompleteHandler(e:Event):void
        {
            //アニメーションデータで定義されているネームからアーマチュアを生成
            armature = factory.buildArmature("Dragon");
            //アーマチュアのdisplayプロパティからスプライトを取得
            armatureClip = armature.display as Sprite;
            
            //スプライトの座標を決めて追加
            armatureClip.x = stage.stageWidth * 0.5;
            armatureClip.y = stage.stageHeight * 0.8;
            addChild(armatureClip);
        }
        
     

静止状態のDragonが表示されました。
今度は、Dragonに動きをつけていきます。

Armatureはanimatonプロパティがアニメーションを担当します。
ArmatureのアニメーションはWorldClockクラスで管理されているため、ArmatureのインスタンスをWorldClockに登録し、フレーム処理イベント内で WorldClock.clock.advanceTime(-1) を実行します。
これにより毎フレーム描画更新が行われ、アニメーションが再生されるようになります。

    import dragonBones.animation.WorldClock;


    //アニメーション更新のためにアーマチュアを追加する
    WorldClock.clock.add(armature);
    //フレームイベント追加
	stage.addEventListener(EnterFrameEvent.ENTER_FRAME, onEnterFrameHandler);


    private function onEnterFrameHandler(_e:EnterFrameEvent):void
    {
        WorldClock.clock.advanceTime(-1);
    }

     

次に、モーションを指定し、実行するアニメーションを変更します。
パースしたファイルがもつモーションデータは、ファイル出力時のDragonBonesパネル上の一覧に出ていたものです。
Dragon.pngの場合は、「stand」「walk」「fall」「jump」4つのモーションを持っています。

Armatureが持つanimationプロパティはMovieClipのため、アニメーション再生には gotoAndPlayメソッドを使用します。

    //standモーション再生
    armature.animation.gotoAndPlay("stand");

    //walkモーション再生
    armature.animation.gotoAndPlay("walk");

    //fallモーション再生
    armature.animation.gotoAndPlay("fall");

    //jumpモーション再生
    armature.animation.gotoAndPlay("jump");

     

以上で、DragonBonesでのボーンアニメーションの基本的な実装は終了となります。
この先は、皆さんそれぞれで応用を加えて、好きなように使用してみてください。

最後まで御覧いただきありがとうございました。

     
     
     

キーボードイベントを追加したサンプルソース(※公式ドキュメントより転載)

internal class StarlinTestMain extends Sprite
{
	//ドラゴン画像
	[Embed(source="./../../../res/img/Dragon.png", mimeType = "application/octet-stream")]
	private var DragonBitmap:Class;
	[Embed(source="./../../../res/img/Cyborg.png", mimeType = "application/octet-stream")]
	private var CyBorgBitmap:Class;

	private var factory			:StarlingFactory;
	private var armature		:Armature;
	private var armatureClip	:Sprite;
	
	private var isLeft			:Boolean;
	private var isRight			:Boolean;
	private var isJumping		:Boolean;
	private var moveDir			:int=0;
	private var speedX			:Number = 0;
	private var speedY			:Number = 0;
	
	public function StarlinTestMain()
    {
		//starling専用のfactoryインスタンスを生成する()
		factory = new StarlingFactory();
		//イベントリスナーを登録する
		factory.addEventListener(Event.COMPLETE, textureCompleteHandler);
		//アニメーションデータをパースする
		factory.parseData(new DragonBitmap());
    }
	
	/**
	 * テクスチャ読み込み完了コールバック
	 */
	private function textureCompleteHandler(e:Event):void
	{
		//アニメーションデータで定義されているネームからアーマチュアを生成
		armature = factory.buildArmature("Dragon");
		//アーマチュアのdisplayプロパティからスプライトを生成
		armatureClip = armature.display as Sprite;
		
		//スプライトの座標を決めて追加
		armatureClip.x = stage.stageWidth * 0.5;
		armatureClip.y = stage.stageHeight * 0.8;
		addChild(armatureClip);

		//アニメーション更新のためにアーマチュアを追加する
		WorldClock.clock.add(armature);

		stage.addEventListener(EnterFrameEvent.ENTER_FRAME, onEnterFrameHandler);
		stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyEventHandler);
		stage.addEventListener(KeyboardEvent.KEY_UP, onKeyEventHandler);
	}
	 
	private function onKeyEventHandler(e:KeyboardEvent):void
	{
		switch (e.keyCode)
		{
			case Keyboard.A :
			case Keyboard.LEFT :
				isLeft = e.type == KeyboardEvent.KEY_DOWN;
				break;
			
			case Keyboard.D :
			case Keyboard.RIGHT :
				isRight = e.type == KeyboardEvent.KEY_DOWN;
				break;
			
			case Keyboard.W :
			case Keyboard.UP :
				jump();
				break;
		}
		
		var dir:int;
		
		if (isLeft && isRight) 
		{
			dir=moveDir;
			return;
		}
		else if (isLeft)
		{
			dir=-1;
		}
		else if (isRight)
		{
			dir=1;
		}
		else
		{
			dir=0;
		}
		if(dir==moveDir)
		{
			return;
		}
		else
		{
			moveDir=dir;
		}
		updateBehavior()
	}
 
	/**
	 * フレーム処理
	 */
	private function onEnterFrameHandler(_e:EnterFrameEvent):void
	{
		updateMove();
		WorldClock.clock.advanceTime(-1);
	}

	/**
	 * アニメーションアップデート
	 */
	private function updateBehavior():void
	{
		if (isJumping)
		{
			return;
		}
		if (moveDir == 0)
		{
			speedX = 0;
			armature.animation.gotoAndPlay("stand");
		}
		else
		{
			speedX=6*moveDir;
			armatureClip.scaleX = -moveDir;
			armature.animation.gotoAndPlay("walk");
		}
	}
	
	/**
	 * 移動アップデート
	 */
	private function updateMove():void
	{
		if (speedX != 0) 
		{
			armatureClip.x += speedX;
			if (armatureClip.x < 0) 
			{
				armatureClip.x = 0;
			}
			else if (armatureClip.x > 800) 
			{
				armatureClip.x = 800;
			}
		}
		
		if (isJumping)
		{
			if (speedY <= 0 && speedY + 1 > 0 ) 
			{
				//落下モーションを再生
				armature.animation.gotoAndPlay("fall");
			}
			speedY += 1;
		}
		
		if (speedY != 0) 
		{
			armatureClip.y += speedY;
			
			if (armatureClip.y > 540) 
			{
				armatureClip.y = 550;
				isJumping = false;
				speedY = 0;
				updateBehavior();
			}
		}
	}
	
	/**
	 * ジャンプイベント
	 */
	private function jump():void
	{
		if (isJumping) 
		{
			return;
		}
		speedY = -25;
		isJumping = true;
		armature.animation.gotoAndPlay("jump");
	}		
}
        

<次回の更新について>
次回は、cocos2d-xでDragonBonesを使用する方法をご紹介致します。


弊社では全国各地の請負い(ご自宅)で作業協力頂ける、フリーランスエンジニアの方を常時探しております。
ご興味ある方は、お気軽にお問い合わせ下さい。


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*