Windows Phone XNAでアニメーション - パラパラ

この投稿ではWindows PhoneのXNA Frameworkで作成したアプリケーションにパラパラ漫画的アニメーションを加える方法を説明します。

※このブログで使う画像、ロジックは、https://create.msdn.com/en-US/education/tutorial/2dgame/getting_started のものをほぼそのまま使用しています。このサンプルは少ない労力でかなり立派なアプリが出来上がるので、是非試してみてくださいね。

例えば敵に弾が当たったときなどに爆発のアニメーションを加えたいな…なんて思いますよね。そんな時には爆発シーンの各コマの画像を作成して、その画像をUpdateで更新し、Drawメソッドでカレントの画像を描画していけば、一定のフレームレート(デフォルトは30fps)で画像がパラパラと描画されます。ですから基本的には、以下のような画像を用意し、

Updateメソッド内で、順次右にずらしていくだけでアニメーションになりますね。

ここで、Drawメソッドの中で、どうやって画像の一部だけを描画するか、その方法が問題になるわけですが、

spriteBatch.Draw(spriteStrip, destinationRect, sourceRect, color);

とします。ここで一番目の引数spriteStripeは、上の図のテクスチャ、二番目の引数は、表示スクリーン上の描画位置を示す四角形、三番目の引数sourceRectは、テクスチャ(爆発の絵)のどの位置を描画するかを示す四角形です。
こんな風に書いて、Updateメソッドで、sourceRectの位置を順番に右にずらしていくと、アニメーションっぽく見えるわけです。

こちらも、ゲームで敵に弾が当たったときの敵機の爆発等を考えればわかるように複数同時に描画されるので、以下のようなクラスを用意しておくと便利です。

    using Microsoft.Xna.Framework;    using Microsoft.Xna.Framework.Content;    using Microsoft.Xna.Framework.Graphics;

    class FrameAnimation    {        Texture2D spriteStrip;        float scale;        int elapsedTime;        int frameTime;        int frameCount;        int currentFrame;        Color color;        Rectangle sourceRect = new Rectangle();        Rectangle destinationRect = new Rectangle();        public int FrameWidth;        public int FrameHeight;        public bool Active;        public bool Looping;        public Vector2 Position;

        public void Initialize(Texture2D texture, Vector2 position,            int frameWidth, int frameHeight, int frameCount,            int frametime, Color color, float scale, bool looping)        {            this.color = color;            this.FrameWidth = frameWidth;            this.FrameHeight = frameHeight;            this.frameCount = frameCount;            this.frameTime = frametime;            this.scale = scale;

            Looping = looping;            Position = position;            spriteStrip = texture;

            elapsedTime = 0;            currentFrame = 0;

            Active = true;        }

        public void Update(TimeSpan elapsedGameTime)        {            if (!Active) return;

            elapsedTime += (int)elapsedGameTime.TotalMilliseconds;

            if (elapsedTime > frameTime)            {                currentFrame++;

                if (currentFrame == frameCount)                {                    currentFrame = 0;                    if (!Looping)                    {                        Active = false;                    }                }                elapsedTime = 0;            }

           // ここでテクスチャーで次に表示する四角形を確定           sourceRect = new Rectangle(currentFrame * FrameWidth, 0, FrameWidth, FrameHeight);            destinationRect = new Rectangle((int)Position.X - (int)(FrameWidth * scale) / 2,                (int)Position.Y - (int)(FrameHeight * scale) / 2,                (int)(FrameWidth * scale),                (int)(FrameHeight * scale));

        }

        public void Draw(SpriteBatch spriteBatch)        {            if (Active)            {                spriteBatch.Draw(spriteStrip, destinationRect, sourceRect, color);            }        }

これで、XNA Game Studio(4.0)のWindows Phone ゲームテンプレートで作ったプロジェクトで生成されるGame1クラスのLoadContentメソッドの中で、

            explosion = Content.Load<Texture2D>("explosion");

※Texture2D型で爆発イメージ用のメンバ変数をexplosionという名前で定義しておき、事前にexplosion.pngという名前のイメージファイルをプロジェクト(名前の最後にContentがついているプロジェクト)に追加しておく

とテクスチャを読み込み、Game1クラスのUpdateメソッドの中の弾と敵が同じ場所を占めたと判断したロジックのところで、

            FrameAnimation animation = new FrameAnimation();
            animation.Initialize(explosion, posiiton, 134, 134, 12, 45, Color.White, 1.0f, false);
            explosionAnimations.Add(animation);

と記述します。※explosionAnimationsは、List<FrameAnimation>型のメンバー変数。予め定義しておいてください。

Game1のDrawメソッドで、

            for (int i = explosionAnimations.Count; i >= 0 ; i--)
            {
                if (explosionAnimations[i].Active)
                {
                    explosionAnimations[i].Draw(spriteBatch);
                }
                else
                {
                    explosionAnimations.RemoveAt(i);
                }
            }

としてやれば、爆発のアニメーションが表示され、表示し終わったら消えていくというアニメーションが出来ます。

こんな小技を使いながら、あなたのゲームに色を添えてくださいね。