Basic Class を継承する

XNA で Basic Class を継承して Shot Class や Char Class を作成します。

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

プログラムの説明

  1. Object Class File では Shot class と Char class を使っていますが、非常に似通っています。
    そこで基本となる Basic Class を作成して、これを継承して Object Class を作成してみましょう。
    基本となる Basic Class は static を使って Base Class を作成 を参照して下さい。
  2. Basic Class を継承した Char class です。
    xn, yn, xs, ys は Base Class で宣言されているのですが static 領域なので一種類にしか対応できません。
    そこで cxn, cyn, cxs, cys を定義して、独自の Draw() メソッドで描画します。
    Char の Constructor から Base の Constructor を呼び出すときは、キーワード(base)を付けて呼び出します。
    C#では、継承する Class は一個しか許されず、基本クラスの Constructor を呼び出すときは base を使います。
    Class を継承する簡単なプログラムは「C#入門」を参照して下さい。
        public class Char : Basic
        {
            public Texture2D img;        //画像の指定
            public int       cxn,cyn;    //横と縦の枚数
            public int       cxs,cys;    //横と縦のサイズ
    
            //コンストラクタ
            //基本クラスのコンストラクタを呼ぶ場合は base を使う。
            public Char(Texture2D Img, Vector2 Pos, Vector2 Vect, int Xn, int Yn, int Sp_no)
                : base(Img, Pos, Vect, Xn, Yn, Sp_no)
            {
                Init(Img, Xn, Yn);
            }
                    ・・・  一部省略  ・・・
    
            //初期値の設定
            private void Init(Texture2D Img, int Xn, int Yn)
            {   img = Img;
                cxn = Xn;
                cyn = Yn;
                cxs = Img.Width / xn;
                cys = Img.Height / yn;
            }
    
            //画像の描画
            public void Draw(SpriteBatch spBatch, Vector2 Pos, int No)
            {   int xw,yw;
    
                if (sp_no < cxn*cyn)
                {   xw= sp_no%cxn;
                    yw= sp_no/cxn;
                    spBatch.Draw(img, Pos, new Rectangle(xw*cxs,yw*cys,cxs,cys),Color.White);
                }
            }
            public void Draw(SpriteBatch spBatch, Vector2 Pos)
            {
                Draw(spBatch, Pos, 0);
            }
            public void Draw(SpriteBatch spBatch)
            {
                Draw(spBatch, pos, 0);
            }
    
            //次の画像番号
            public void Loop()
            {
                if (sp_no < xn*yn)  sp_no = (sp_no+1) % (xn * yn);
            }
        }
    
  3. Base Class を継承した Shot class です。
    Shot Class は乱れ飛ぶ多数の弾丸にも対応出来るように極力軽くしています。
    Char Class では独自の Draw() メソッドを作成しましたが、ここでは Base Class のものを使います。
    今回は4枚のスプライトを横に並べた一種類の画像を使っています。

    詳細は「敵の多様な攻撃」を参照して下さい。
        public class Shot : Basic
        {
            public static Texture2D img;        //画像の指定
            private double          tim;        //アニメタイム
    
            //コンストラクタ
            public Shot(Texture2D Img, Vector2 Pos, Vector2 Vect, int Xn, int Yn, int Sp_no)
                : base(Img, Pos, Vect, Xn, Yn, Sp_no)
            {
                img = Img;
                tim = 0;
            }
                    ・・・  一部省略  ・・・
    
            //画像の描画
            public void Draw(SpriteBatch spBatch, Vector2 Pos, int No)
            {
                Draw(spBatch, img, Pos, No);
            }
            public void Draw(SpriteBatch spBatch, Vector2 Pos)
            {
                Draw(spBatch, img, Pos);
            }
            public void Draw(SpriteBatch spBatch)
            {
                Draw(spBatch, img);
            }
    
            //座標の移動と Window 外の判定
            public bool Move(Rectangle rect)
            {
                if (sp_no >= xn*yn) return false;
                pos = pos + vect;
                if (pos.X<rect.Left || pos.X>=rect.Right || pos.Y<rect.Top || pos.Y>=rect.Bottom)
                {   sp_no = 99;
                    return true;
                }
                return false;
            }
            public bool Move()
            {
                return Move(new Rectangle(0,0,800,600));
            }
    
            //当たり判定
            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;
            }
            public bool Hit(Vector2 target)
            {
                return Hit(target,30);
            }
    
            //次の画像番号
            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);
                }
            }
            public bool Next(GameTime gameTime, double Tim)
            {
                if (sp_no < xn * yn)
                {   double nowtim = gameTime.TotalGameTime.TotalMilliseconds;
                    if (tim + Tim < nowtim)
                    {   tim = nowtim;
                        sp_no++;
                    }
                }
                if (sp_no >= xn * yn)
                {   sp_no = 99;
                    return true;
                }
                return false;
            }
    
            //回転計算(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;
            }
        }
    
  4. 各 Object Class では、使い勝手が良いように様々なコンストラクタの形式を定義しています。
    主プログラム(Class Game1)で使われているコンストラクタの形式が定義されていないときは追加して下さい。
    主プログラムプログラムは「敵の多様な攻撃」と変わらないので、後は各自でプログラムを完成させて下さい。

【NOTE】

今回追加した Draw()メソッドは、継承元のメソッドとはパラメータが違うので、新たなメソッドとして追加されます。
継承元のメソッドをオーバーライド(上書き)するときは、C#では new 演算子を使います。
例えば、次のように書きます。
public new void Draw(SpriteBatch spBatch)
{
    :
    :
    :
}

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

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