TEXT FILE で Enemy の動きを設定する

Enemy の動きを定義した Motion.txt を入力して、乱数で移動コースを選択して動かします。
キー操作で動かすオブジェクトを Enemy から Enterprise に切り替えます。

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

プログラムの説明

  1. Spin Button で3Dモデルの姿勢を操作 で作成した TEXT DATA で Enemy を動かします。
    モデルの動きを定義した Motion.txt の例です。
        // Motion Frame  Ver 1.0   by Maeda Minoru
        1,        //パーツの数
        Enemy3.x,
    
        // キーフレーム - 0
        *  100,
            0.00,  0.00, -500.00,     0.00,  0.00,  0.00,   872.00,  550.00, 1000.00,    -0.20,  0.60,  0.00,
    
        // キーフレーム - 1
        *  100,
            0.00, 50.00, -500.00,     0.00,  0.00,  0.00,   385.00,  174.00,  750.00,    -0.10,  1.20,  0.20,
                :
    
        // キーフレーム - 4
        *  100,
            0.00, 50.00, -500.00,     0.00,  0.00,  0.00,  -120.00,  280.00,  700.00,    -0.30,  0.00,  0.00,
                :
    
        // キーフレーム - 10
        *  100,
            0.00, 50.00, -500.00,     0.00,  0.00,  0.00,  -120.00,  280.00,  700.00,    -0.30,  0.00,  0.00,
                :
        
  2. Motion.txt の説明です。
    私が作成したプログラムは複数のメッシュを組み合わせてアニメーションができるようになっています。
    「1」は組み合わせるパーツ(メッシュ)の個数で、次の行からXファイル名が記述されています。
    「* 100」はキーフレーム間を何分割するかの設定です。
    [キーフレーム - 4] が Home Position で、Z座標の 700.0 をプログラムで判定して Home Position を識別します。
    Home Position を基点に複数のコースから乱数で選んで動かします。
    このファイルでは次のようにコースを設定しています。
    1. 一番目のコース
      [キーフレーム - 4][キーフレーム - 5][キーフレーム - 6]・・・と進みます。
    2. 二番目のコース
      [キーフレーム - 10][キーフレーム - 11][キーフレーム - 12]・・・と進みます。
    3. 三番目のコース
      [キーフレーム - 15][キーフレーム - 16][キーフレーム - 17]・・・と進みます。
    どのコースも Home Position に戻るようになっていて、次にどのコースを取るかは乱数で選択します。
    Home Position に戻るとき、一回り以上の回転を防ぐようにプログラムしなければなりません。
  3. Global variables の定義です。
    HOME は Home Position の定義です。
    COURSE は設定されたコースの数です。
    KT[K_MAX] はキーフレーム間を何分割するかのテーブルです。
    VT[K_MAX][12] が Enemy を描画する環境設定のテーブルです。
        #define     WINDWIDTH   800         //Windows Width
        #define     WINDHEIGHT  600         //Windows Height
        #define     K_MAX       100         //キーフレームの最大数
        #define     HOME        4           //Home Position
        #define     COURSE      5           //コースの数
    
        //Motion.txt で Enemy を移動
        //View(XYZ), Terg(XYZ), 移動(XYZ), 回転(XYZ)
        int         g_num;                  // 現在描画中のキーフレーム番号
        float       g_Weight;               // ブレンドの度合い(1.0→0.0)
        float       g_dt;                   // g_Weight の増加係数(1.0/KT[g_num])
        int         g_XN= 1;                // X-file(Mesh) の個数
        int         g_KN;                   // Key Frame 数
        char        g_file[24];             // X-File Name
        int         KT[K_MAX];              // Key Frame Motion Count
        float       VT[K_MAX][12];          // View Motion Table
        char        g_buf[32000];           // KeyFrame.txt 入力 Buffer
        //Enemy の座標
        D3DVECTOR   *g_Target= ⌖
        
  4. Motion.txt からパラメータを入力して格納する関数です。
    格納が終わると g_dt と g_Weight を設定して Enemy の描画を開始します。
        void  SetParam()
        {   char    *p;
            int     xn;
    
            ReadData("Motion.txt",g_buf,32000);
            p= SetInt(&xn,g_buf,1);         // パーツの個数を取得
            p= SetStr(g_file,p);            // XーFile Name を格納
            for(g_KN=0; *p && g_KN<K_MAX; g_KN++)
            {   for(; *p && *p!='*'; p++);
                if (*p=='*')
                {   p= SetInt(&KT[g_KN],p+1,1);
                    p= SetFloat(VT[g_KN],p,12);
                }
                else    break;
            }
            g_num= 0;
            g_dt= 1.0f/KT[g_num];
            g_Weight= 1.0f;
        }
        
  5. FrameMove2() で Enemy の描画環境を設定します。
    g_Weight が Blend の度合いで if (g_Weight<g_dt) でキーフレームを切り替えます。
    キーフレームが Home Position に戻ったときに、次のコースを乱数で決めます。
    g_Weight= 1.0f; で、次のキーフレーム間のアニメーションが開始されます。
    BlendFrame() でキーフレームを Blend して描画します。
        HRESULT FrameMove2()
        {   D3DXMATRIX  matWorld,matWork;
            int         i;
    
            if (g_Weight<g_dt)                      //キーフレーム間のアニメ終了
            {
                if (VT[g_num+1][8]==VT[HOME][8])    //Home Position
                {   i= rand()%COURSE;
                    g_num= HOME;
                    while(i>0)                      //i番目のコースに設定
                    {   for(g_num++; VT[g_num][8]!=VT[HOME][8]; g_num++);
                        i--;
                    }
                    g_Weight= 1.0f;
                }
                else
                {   if (g_num<(g_KN-2))
                    {   g_num++;
                        g_dt= 1.0f/KT[g_num];
                        g_Weight= 1.0f;
                    }
                    else                            //最後のキーフレーム
                    {   g_num= 0;
                        g_Weight= 1.0f;
                    }
                }
            }
            BlendFrame(g_pDEV,&viewForm,&tergForm,VT[g_num],VT[g_num+1],g_Weight);
            if (g_Weight>g_dt)  g_Weight-= g_dt;
            return S_OK;
        }
        
  6. 矢印キーの操作で Enterprise を移動します。
        void KeyCheck()
        {   BYTE    KeyBuffer[256];
            int     i;
    
            // キーボードの状態を読み取る
            GetKeyboardState(KeyBuffer);
            if (KeyBuffer[VK_ESCAPE]&0xf0)              //ESC
            {   PostMessage(g_hWnd,WM_CLOSE,0,0);       //WM_CLOSE をポスト
                return;
            }
            // キーの操作で移動
            if (GetKeyState(VK_LEFT)<0 && start.x>-260.0f)  start.x -= 5.0f;
            if (GetKeyState(VK_RIGHT)<0 && start.x<260.0f)  start.x += 5.0f;
            if (GetKeyState(VK_DOWN)<0 && start.y>-200.0f)  start.y -= 5.0f;
            if (GetKeyState(VK_UP)<0 && start.y<0.0f)       start.y += 5.0f;
            // Space キーで最大8発の弾を連射
            if ((shtime+200)<nowtime && (KeyBuffer[VK_SPACE]&0xf0))
            {   for(i=0; i<8 && flag[i]==TRUE; i++);
                if (i>=8)   return;
                vect[i]= start;
                step[i].x= (target.x-start.x)/100.0f;
                step[i].y= (target.y-start.y)/100.0f;
                step[i].z= (target.z-start.z)/100.0f;
                flag[i]= TRUE;
                vtime[i]= nowtime+2000;
                shtime= nowtime;
            }
        }
        

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

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

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