Windows Phone XNAでアニメーション - ぐるぐる
この投稿では、Windows PhoneでGameなどの高機能なグラフィックスを必要とするアプリケーション開発に最適な、XNA Frameworkを使って、テクスチャイメージを一定の速さで変形させる方法を解説します。
ここでは図のテクスチャを一定速度で回転させるアニメーションをベースに説明を行います。
この画像は、PowerPoint 2010で、フリーハンドでぐるぐるを描いて、図としてPNGで保存したものです。背景が透明なので他の描画に重ねることができます。好きな画像を用意してください。
次に、Windows Phone SDKをインストールしたVisual Studioを起動して、XNA Game Studio 4.0のWindows Phone ゲーム(4.0)という名前のテンプレートで新しくプロジェクトを作成します。名前を仮にWPGuruGuruとしておきます。
作っておいた図を、新しく作成されたプロジェクトのフォルダーWPGuruGuruContentにコピーします。
そして、WPGuruGuruのソリューションエクスプローラーで、新しく作成されたソリューションの2つのプロジェクトのうち、お尻にContentがついたプロジェクト(ここではWPGuruGuruContent)をマウスで右クリックし、”追加”→”既存の項目”を選択して、この画像ファイルをこのプロジェクトに追加します。画像ファイル名は、GuruGuru.pngとしておきますね。
WPGuruGuruプロジェクトのGame1.csのGame1クラスのメンバー変数として、
private Texture2D guruguruTexture; // 画像を保持する為のメンバー変数
private float angle; // 画像を描画する時の角度
private float deltaAngle; // 画像角度を更新する際の単位角度
を追加します。
そして、Game1クラスのLoadContentメソッドに、以下のコードを加えます。
guruguruTexture = Content.Load<Texture2D>("GuruGuru");
XNAの場合、(デフォルトで)毎秒30回、描画内容の更新(Updateメソッド)、描画(Drawメソッド)がコールされます。Updateメソッドで、angleにdeltaAngleを足して、360度を超えたら、360度の剰余を代入して、angleを順次更新していきます。そして、Drawメソッドで、そのangleの角度でテクスチャ画像を描画すれば、ぐるぐる回っているアニメーションの出来上がりです。なので、Initializeメソッドでangleを0、deltaAngleを10で、初期化しておいて、
Updateメソッドで、
angle += deltaAngle;
if (angle >= 360) angle %=360;
と描いておき、Drawメソッドで、
Vector2 origin = new Vector(guruguruTexture.Width / 2, guruguruTexture.Height / 2);
spriteBatch.Draw(guruguruTexture, Position, null, Color.White, angle, origin, 1f, SpriteEffects.None, 0f);
とすると、更新された角度でぐるぐるが描画されます。spriteBatchのDrawメソッドの引数のうち、このポストに絡むものを説明すると、
1番目: アニメーションしたいテクスチャ画像
2番目: 描画する場所(適当に描画する場所を決めておく)
5番目: テクスチャ画像を描画する角度
6番目: 回転中心。ここではテクスチャ画像の真ん中を指定
7番目: 描画する際の拡大縮小率。1にすると同じサイズで描画
です。もし、テクスチャをブルブルさせたければ、Positionにぶるぶるを与えた様な変動をUpdateメソッドで代入すればよいし、大きくしたり小さくしたりしたい場合には、7番目の引数をUpdateで適宜設定してやれば、OKです。
例えばゲームを開発する場合など、複数の場所に対してこのぐるぐるアニメーションを適用したい場合もあるでしょう。ですから実用を考えて、以下のようなクラスを作ると便利。
using Microsoft.Xna.Framework; class RotateAnimation private int currentFrame; public void Initialize(Texture2D texture, Vector2 position, spriteStrip = texture; Active = true; origin.X = spriteStrip.Width / 2; currentFrame = 0; private float rotateAngle = 0; public void Update(TimeSpan elapsedGameTime) public void Draw(SpriteBatch spriteBatch) |
このクラスは、Initializeメソッドの引数でframeCountを0にすると、ずっと回転し、1以上にすると、Updateがその指定回数だけコールされると、Activeがfalseに設定し、規定回数分アニメーションを実行したことがわかるようになっています。
Game1クラスのメンバーに、このクラス用のコンテナを宣言し、
private List<RotateAnimation> rotateAnimations = new List<RotateAnimation>();
Game1のUpdateメソッドの中で、このリストに登録されたぐるぐるアニメのUpdateメソッドをコールし、このぐるぐるアニメーションが必要と条件判断がなされたところで、リストに追加するという処理を加えます。
foreach (var guruguruA in guruguruAnimation)
{
guruguruA.Update();
}
…
// 以下適切な場所で、
RotateAnimation guruguru = new RotateAnimation();
guruguru.Initialize(guruguruTexture, position, 20, 100, Color.White, 1.0f);
guruguruAnimations.Add(guruguru);
とし、Game1クラスのDrawの中で、
for (int i = guruguruAnimations.Count ; i >= 0 ; i--)
{
if (guruguruAnimations[i].Active)
{
guruguruAnimations[i].Draw(spriteBatch);
}
else
{
guruguruAnimations.RemoveAt(i);
}
}
と書けば、Activeなぐるぐるのみ描画して、既に規定回数描画したものは、リストから削除される訳です。
ゲーム等の色づけでのワンポイントアクセントとしてお使いください。