Image Class でアニメーション

XNA で Image Object Class を定義してアニメーションを行います。
spriteBatch で直接アニメーションするプログラムは spriteBatch でアニメーション を参照して下さい。

前田稔(Maeda Minoru)の超初心者のプログラム入門

プログラムの説明

  1. メニューから [ファイル][新規作成][プロジェクト] で新しいプロジェクトを作成して下さい。
    Game1.cs を編集して Image Object Class を使ってアニメーションをするプログラムを作成します。
    プログラムの最初(namespace Main の直後)に Image Object Class を定義します。
    Image Object Class の説明は、このページの後部に掲載しています。
    namespace Main
    {
        #region ★Image Object Class
        public class Image
        {
            //Image Object Class を定義する
        }
        #endregion
    
  2. class Game1 の最初に次の領域を宣言して下さい。
    myTexture は、アニメーションに使用する画像をロードする領域です。
    image; は Image Object Class です。
        public class Game1 : Microsoft.Xna.Framework.Game
        {
            GraphicsDeviceManager graphics;
            SpriteBatch spriteBatch;
            Texture2D   myTexture;     // 描画に使用するテクスチャ
            Image       image;         // イメージクラス
        
  3. LoadContent() メソッドで画像をロードして、Image Object Class を初期化します。
    Bijin16.jpg がアニメーションに使う画像です。
    4,4 は画像を切り分ける数値で、列数(横に並べた枚数)と行数(縦に並べた枚数)を渡します。
    image.sp_no は切り分けた画像の何枚目を描画するかの設定で、最初はゼロ番の画像に設定しています。
        myTexture = Texture2D.FromFile(graphics.GraphicsDevice, "c:\\data\\test\\Bijin16.jpg");
        image = new Image(myTexture,4,4);
        image.sp_no = 0;
        
  4. Draw() メソッドに画像を描画するコードを記述します。
    XNA ではコンシューマゲームと同様に例え同じ画面でも毎回画面をクリアして再描画しなければなりません。
    image.Loop(gameTime,200);で画像の番号(image.sp_no)を切り替えます。
    200 は画像を切り替える速度(アニメーションの速度)です。
            protected override void Draw(GameTime gameTime)
            {
                graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
    
                // TODO: Add your drawing code here
                spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
                image.Draw(spriteBatch, new Vector2(100, 100));
                image.Loop(gameTime,200);
                spriteBatch.End();
    
                base.Draw(gameTime);
            }
        
  5. メニューからコンパイルして実行して下さい。

Image Class 全体の説明

  1. 画像を管理する Image Object Class です。
    sp_no は画像を分割して描画するときの Sprite の番号で、描画しないときは 99 を格納します。
    img は描画する画像です。
    xn,yn は画像を分割するときの、横と縦の枚数です。
    xs,ys は画像を分割したときの一枚あたりの Sprite のサイズです。
    pos は Sprite を描画する現在の座標です。
    vct は座標の移動の方向と量で、Move() メソッドで pos に加えられます。
    tim はアニメーションの時間を調整する領域です。
    width と height は Window のサイズです。
    #region ★Image Object Class
    public class Image
    {
        public int       sp_no;     //Sprite No
        public Texture2D img;       //画像の指定
        public int       xn,yn;     //横と縦の枚数
        public int       xs,ys;     //横と縦のサイズ
        public Vector2   pos;       //弾の座標
        public Vector2   vect;      //進行方向
    
        private double   tim;       //アニメタイム
        private float    width;     //Window の幅
        private float    height;    //Window の高さ
        
  2. コンストラクタは「画像の分割や、ウインドウサイズの設定」などの関係で複数のメソッドを用意しています。
    Init() はコンストラクタから呼び出され、Image Class を初期化します。
        //コンストラクタ
        public Image(Texture2D Img, int Xn, int Yn, float Width, float Height)
        {
            Init(Img, Xn, Yn, Width, Height);
        }
        //初期値の設定
        private void Init(Texture2D Img, int Xn, int Yn, float Width, float Height)
        {   img = Img;
            sp_no = 99;
            xn = Xn;
            yn = Yn;
            xs = img.Width / xn;
            ys = img.Height / yn;
            pos  = Vector2.Zero;
            vect = Vector2.Zero;
            tim = 0;
            width = Width;
            height= Height;
        }
        
  3. 画像の描画を行う Draw() メソッドです。
    座標の指定や Sprite 番号の指定など、複数のメソッドを用意しています。
        //画像の描画
        public void Draw(SpriteBatch spBatch, Vector2 Pos, int No)
        {   int xw,yw;
    
            if (No < xn*yn)
            {   xw= No%xn;
                yw= No/xn;
                spBatch.Draw(img, Pos, new Rectangle(xw*xs,yw*ys,xs,ys),Color.White);
            }
        }
        
  4. 座標の移動と、座標が Window 外に出たことを調べる Move() メソッドです。
    矩形範囲(Rectangle)を指定するメソッドと、Window サイズで判定するメソッドを用意しています。
    座標がウインドウ(矩形範囲)の外に出ると sp_no に 99 を設定して描画を停止します。
        //座標の移動と Window 外の判定
        public void Move(Rectangle rect)
        {
            if (sp_no < xn*yn)
            {   pos = pos + vect;
                if (pos.X<rect.Left || pos.X>rect.Right || pos.Y<rect.Top || pos.Y>rect.Bottom)
                    sp_no = 99;
            }
        }
        
  5. Sprite の番号(sp_no)を次の画像に設定するメソッドです。
    Next() は最後の Sprite が終わると描画を off にしますが、Loop() は最初に戻ります。
    Next() は爆発のアニメーション、Loop() は繰り返し行うキャラクタのアニメーションなどに使います。
        //次の画像番号
        public void Next(GameTime gameTime, double Tim)
        {
            if (sp_no < xn * yn)
            {   double nowtim = gameTime.TotalGameTime.TotalMilliseconds;
                if (tim + Tim < nowtim)
                {   tim = nowtim;
                    sp_no++;
                }
            }
            else sp_no = 99;
        }
        public void Loop(GameTime gameTime, double Tim)
        {
            double nowtim = gameTime.TotalGameTime.TotalMilliseconds;
            if (sp_no < xn * yn && tim + Tim < nowtim)
            {   tim = nowtim;
                sp_no = (sp_no + 1) % (xn * yn);
            }
        }
        
  6. 当たり判定を行う Hit() メソッドです。
    target と pos が len より近づいたかを判定します。
        //当たり判定
        public bool Hit(Vector2 target, float len)
        {   float dist;
            float wx;
            float wy;
    
            if (sp_no > xn*yn)  return false;
            wx = pos.X - target.X;
            wy = pos.Y - target.Y;
            dist = (float)Math.Sqrt((double)(wx * wx + wy * wy));
            if (dist<len)       return true;
            return false;
        }
        
  7. 回転座標を計算する Rot() メソッドです。
    回転角度(rt) の方向を vect に設定します。
    len は回転半径で、大きくすると移動速度が早くなります。
        //★ 回転計算(rt=度)、中心(0,0)、半径(len)
        public void Rot(float rt, float len)
        {
            vect.X = (float)(Math.Sin(rt / 180 * 3.14)) * len;
            vect.Y = (float)(Math.Cos(rt / 180 * 3.14)) * len;
        }
       
  8. 具体的な使い方は、この後のホームページを参照して下さい。

【演習】

  1. 適当なアニメーション用の画像を調達して来て、動かしてみて下さい。
    Image Object Class を使えば簡単にアニメーションを行うことが出来ます。
  2. 透明色を設定した png 画像を使えば、背景画像をバックにアニメーションすることが出来ます。
    BMP 画像で透明色を使う方法は 画像をリソースとして組み込む を参照して下さい。

超初心者の方のために全ソースコードを掲載します。 (^_^;)
全ソースコード

前田稔(Maeda Minoru)の超初心者のプログラム入門

超初心者のプログラム入門(XNA(C#) game program)