トップページ > ゲーム制作 > アニメーションパターンを登録、再生させる



概要

addAnimation("play", [0, 1, 2, 3, 4, 5, 6, 7], 1 / 10, true);
play("play");
 
  • addAnimation(アニメパターン名, 再生する順番(インデックス), インデックスを切り換えるウェイト, ループするかどうか)
  • play(再生するアニメパターン名)
でチップからパターンを切り出し、アニメーションを再生させます。


プログラム

Anim.as
package
{
	public class Anim
	{
		public var frames:Array;	// 再生する順番(インデックス)を入れた配列
		public var index:int;		// frames配列のインデックス
		public var delay:Number;	// パターンを切り換えるウェイト
		public var name:String;		// パターン名
		public var looped:Boolean;	// ループするならtrue
 
		public function Anim(name:String, frames:Array, index:int, delay:Number, looped:Boolean):void
		{
			this.name = name;
			this.frames = frames;
			this.index = index;
			this.delay = delay;
			this.looped = looped;
		}
	}
}
 
アニメーションに必要な情報を保持するAnimクラスです。


AnimSprite.as
package
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.geom.Point;
	import flash.geom.Rectangle;
 
	public class AnimSprite extends Sprite
	{
		public static var stage:Stage;			// stage
		public static const ZERO:Point = new Point();	// Point(0, 0)
		public var curAnim:Anim;			// 再生するアニメーション
		public var animGroup:Array = [];		// 登録されたパターンを入れている配列
		public var finished:Boolean = false;		// 再生が終わったらtrue
		public var time:Number = 0.0;			// 経過時間
		public var chip:BitmapData;			// 再生するチップ
		public var chipWidth:Number;			// チップ内のデータ一つあたりの幅
		public var chipHeight:Number;			// チップ内のデータ一つあたりの高さ
		public var xLength:int;				// チップ一行あたりに何枚のデータが並んでいるか
		public var bitmap:Bitmap;			// 切り出したデータを描画するBitmap
 
		public function AnimSprite(chip:BitmapData, width:Number, height:Number)
		{
			this.chip = chip;
			this.chipWidth = width;
			this.chipHeight = height;
			this.xLength = chip.width / width;
 
			var bd:BitmapData = new BitmapData(width, height, true, 0x0);
			addChild(bitmap = new Bitmap(bd));
		}
 
		public function addAnimation(name:String, frames:Array, delay:Number, looped:Boolean):void
		{
			animGroup.push(new Anim(name, frames, 0, 1.0 / delay, looped));
		}
 
		public function play(name:String, force:Boolean = false):void
		{
			// forceがtrueなら強制的に引数のAnimに切り替える
			// falseの場合の再生条件は、下記のどれかを満たしている場合
			// ■curAnimがnullである
			// ■Animの名前が違う
			// ■Animの名前が一緒だが、Animがループ対応 or 既に再生が終了している
			if (!force && curAnim != null && anim.name == name && (anim.looped || !finished)) return;
 
			// animGroupからnameを持つAnimを探し出す
			for each (var anim:Anim in animGroup)
			{
				if (anim.name == name)
				{
					curAnim = anim;		// 現在再生しているAnimにする
					finished = false;	// 初期化
					time = 0.0;		//
					break;
				}
			}
		}
 
		public function update():void
		{
			// Animのインデックス情報をもとにチップからデータを切り出し、Bitmapに描画する
			bitmap.bitmapData.fillRect(bitmap.bitmapData.rect, 0x0);
			if (curAnim)
			{
				var tx:int = curAnim.frames[curAnim.index] % xLength;
				var ty:int = curAnim.frames[curAnim.index] / xLength;
				bitmap.bitmapData.copyPixels(chip, new Rectangle(tx * chipWidth, ty * chipHeight, chipWidth, chipHeight), ZERO);
			}
 
			if (curAnim && curAnim.delay > 0 && (curAnim.looped || !finished))
			{
				// 1フレームあたりの時間を進める
				time += 1 / AnimSprite.stage.frameRate;
				// delay秒経ったらインデックス更新
				while (time > curAnim.delay)
				{
					time -= curAnim.delay;
 
					// 最後のフレームまで再生したら
					if (curAnim.index >= curAnim.frames.length - 1)
					{
						finished = true;
						// ループするならインデックスを0に戻す。
						if (curAnim.looped) curAnim.index = 0;
					}
					else curAnim.index++;
				}
			}
		}
	}
}
 

Fire.as
package
{
	import flash.display.Bitmap;
 
	public class Fire extends AnimSprite
	{
		[Embed(source = "images/effect.png")] private var effectPNG:Class;
 
		public function Fire()
		{
			var bitmap:Bitmap = new effectPNG() as Bitmap;
			super(bitmap.bitmapData, 48, 48);
			addAnimation("play", [0, 1, 2, 3, 4, 5, 6, 7], 1 / 10, true);
			play("play");
			scaleX = scaleY = 2.5;
		}
	}
}
 

Main.as
package
{
	import flash.display.Sprite;
	import flash.events.Event;
 
	public class Main extends Sprite
	{
		private var animGroup:Array = [];
 
		public function Main()
		{
			graphics.beginFill(0x0);
			graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
			graphics.endFill();
 
			AnimSprite.stage = stage;
			animGroup.push(addChild(new Fire()));
			addEventListener(Event.ENTER_FRAME, onEnterFrame);
		}
 
		private function onEnterFrame(event:Event):void 
		{
			// 全てのAnimSpriteを更新
			for each (var anim:AnimSprite in animGroup)
			{
				anim.update();
			}
		}
	}
}
 


実行結果

flash on 2011-5-19 - wonderfl build flash online



検証用コード

使用画像
./images/effect.png

Main.as
+ ...

AnimSprite.as
+ ...

Anim.as
+ ...

Fire.as
+ ...

|新しいページ|検索|ページ一覧|RSS|@ウィキご利用ガイド | 管理者にお問合せ
|ログイン|
添付ファイル