爆発のアニメーション

Enemy に弾がヒットして爆発するアニメーションを描画します。

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

プログラムの説明

  1. Global variables の定義です。
    bomb_t はアニメーション画像を切り替えるタイミングを計る領域です。
    bomb_c は Sprite の番号を格納する領域で 16 → 0 に変わり、0 のときは描画を行いません。
    vtbomb[4] はアニメーション画像を貼り付ける矩形ポリゴンです。
        //Audio Object Class
        Audio       AUDIO;
        char        SEFile[24]= "14_5.wav";
    
        //弾発射の座標計算領域
        D3DVECTOR               start= { -80.0f,-50.0f,0.0f };  // 発射座標(Enterprise)
        D3DVECTOR               target={ 220.0f,100.0f,300.0f };// 目標座標(Enemy)
    
        //着弾のアニメーション
        LPDIRECT3DTEXTURE9      g_pBombTex = NULL;
        char                    BombFile[] = "bomb.jpg";
        DWORD                   bomb_t;                         // Bomb 描画切替
        int                     bomb_c= 0;                      // 着弾アニメの制御
    
        //矩形ポリゴンの定義
        D3D_CUSTVERTEX vtbomb[4]=
        {   {   -50,   50,   -50,  0xffffffff, 0, 0  },   //左上
            {    50,   50,   -50,  0xffffffff, 1, 0  },   //右上
            {   -50,  -50,   -50,  0xffffffff, 0, 1  },   //左下
            {    50,  -50,   -50,  0xffffffff, 1, 1  },   //右下
        };
        
  2. InitGraphics() で、背景画像に続いて着弾画像をロードします。
    着弾画像はレンダリングした上から描画するので「透明色」を設定して下さい。
        HRESULT InitGraphics(HWND hWnd)
        {        :
                 :
            //背景 Texture 画像をロード
            if (FAILED(D3DXCreateTextureFromFile(g_pDEV,BgFile,&g_pTexture)))
            {   MessageBox(NULL,BgFile,"Texture Load Error",MB_OK);
                return FALSE;
            }
            //着弾画像をロード
            if (FAILED(D3DXCreateTextureFromFileEx(g_pDEV,BombFile,0,0,0,0,
                D3DFMT_A8R8G8B8,D3DPOOL_MANAGED,D3DX_FILTER_NONE,D3DX_FILTER_NONE,
                D3DCOLOR_ARGB(255,0,0,0),NULL,NULL,&g_pBombTex)))
            {   MessageBox(NULL,BombFile,"Texture Load Error",MB_OK);
                return FALSE;
            }
            return TRUE;
        }
        
  3. レンダリング環境の設定は、モデルの種類やアニメーションで別々に行って下さい。
    Enterprise のレンダリング環境を設定します。
    表示座標と向きを設定して描画します。
        HRESULT FrameMove1()
        {   D3DXMATRIX  matWorld,matWork;
            //画面の左に移動
            D3DXMatrixTranslation(&matWorld,start.x,start.y,start.z);
            //正面から後右向きに回転
            D3DXMatrixRotationY(&matWork,-2.8f);
            matWorld= matWork * matWorld;
            g_pDEV->SetTransform(D3DTS_WORLD,&matWorld);
            return S_OK;
        }
        
  4. Enemy の座標のレンダリング環境を設定します。
    表示座標と向きを設定して描画します。
        HRESULT FrameMove2()
        {   D3DXMATRIX  matWorld,matWork;
            //画面の右に移動
            D3DXMatrixTranslation(&matWorld,target.x,target.y,target.z);
            //正面から左向きに回転
            D3DXMatrixRotationY(&matWork,0.4f);
            matWorld= matWork * matWorld;
            g_pDEV->SetTransform(D3DTS_WORLD,&matWorld);
            return S_OK;
        }
        
  5. Torpedo(トーピードウ)のレンダリング環境を設定します。
    D3DVECTOR vect[10]; が描画する座標です。
    Z座標が500を超えるとフラグをリセットします。
    Torpedo のヒットを検出すると爆発音を鳴らします。
    爆発音に続いて「bomb_c に 16 を設定」してアニメーションを開始します。
        HRESULT FrameMove3(int n)
        {   D3DXMATRIX  matWorld,matWork;
            float       dttime;
    
            dttime= (nowtime-oldtime)/20.0f;
            vect[n].x+= step[n].x*dttime;
            vect[n].y+= step[n].y*dttime;
            vect[n].z+= step[n].z*dttime;
            if (vect[n].z>500.0f)   flag[n]= FALSE;
            //座標の移動
            D3DXMatrixTranslation(&matWorld,vect[n].x,vect[n].y,vect[n].z);
            g_pDEV->SetTransform(D3DTS_WORLD,&matWorld);
            //当たり判定
            if (vect[n].x<target.x-20 || vect[n].x>target.x+20) return S_OK;
            if (vect[n].y<target.y-15 || vect[n].y>target.y+15) return S_OK;
            if (vect[n].z<target.z-20 || vect[n].z>target.z+40) return S_OK;
            //AUDIO.Load(SEFile);
            AUDIO.Play();
            flag[n]= FALSE;
            bomb_c= 16;
            return S_OK;
        }
        
  6. 背景ポリゴンにテクスチャを貼り付けてスクロールします。
    タイマを取得して背景テクスチャのスクロールを制御します。
        HRESULT FrameMove()
        {   float       ofst;
            DWORD       tim;
            D3DXMATRIX  matWorld;
    
            tim= timeGetTime();
            D3DXMatrixIdentity(&matWorld);
            g_pDEV->SetTransform(D3DTS_WORLD,&matWorld);
            g_pDEV->SetTexture(0,g_pTexture);
            ofst= (float)(tim%50000)/50000.0f;
            vtx[0].tu=vtx[1].tu= 1-ofst;
            vtx[0].tv=vtx[2].tv= ofst;
            vtx[2].tu=vtx[3].tu= vtx[0].tu+1.0f;
            vtx[1].tv=vtx[3].tv= vtx[0].tv+1.0f;
            return S_OK;
        }
        
  7. 爆発のアニメーションを設定する FrameMoveBomb() です。
    Enemy と同じ座標にアニメーションを描画します。
    レンダリングした上から描画するので、透明色を使うアルファテストを設定して下さい。
    int bomb_c; が着弾アニメーションの画像番号です。
    if (nowtime>bomb_t+200) で画像を切り替えるタイミングを計ります。
    AMBIENT に 0xffffffff を設定して、明るくはっきりと描画しています。
        HRESULT FrameMoveBomb()
        {   D3DXMATRIX  matWorld;
            float       xn,yn;
    
            D3DXMatrixTranslation(&matWorld,target.x,target.y,target.z);
            g_pDEV->SetTransform(D3DTS_WORLD,&matWorld);
            //カラーキー用アルファテスト
            g_pDEV->SetRenderState(D3DRS_ALPHATESTENABLE,TRUE);
            g_pDEV->SetRenderState(D3DRS_ALPHAREF,0x80);
            g_pDEV->SetRenderState(D3DRS_ALPHAFUNC,D3DCMP_GREATEREQUAL);
            g_pDEV->SetTexture(0,g_pBombTex);
            xn= (15-bomb_c)%4;
            yn= (15-bomb_c)/4;
            vtbomb[0].tu=vtbomb[2].tu= xn*0.25f;
            vtbomb[0].tv=vtbomb[1].tv= yn*0.25f;
            vtbomb[1].tu=vtbomb[3].tu= vtbomb[0].tu+0.25f;
            vtbomb[2].tv=vtbomb[3].tv= vtbomb[0].tv+0.25f;
            if (nowtime>bomb_t+200)
            {   bomb_t= nowtime;
                bomb_c--;
            }
            g_pDEV->SetRenderState(D3DRS_AMBIENT,0xffffffff);
            SetLight(g_pDEV);
            SetMaterial(g_pDEV);
            return S_OK;
        }
        
  8. Render() 関数で bomb_c が設定されているときは FrameMoveBomb() で爆発のアニメーションを描画します。
    ヒットしたときに bomb_c に16が格納されて、アニメーションが始まります。
        VOID Render()
        {   DWORD   i,n;
    
            g_pDEV->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,50,50),1.0f,0);
            if (SUCCEEDED(g_pDEV->BeginScene()))
            {   //描画環境の設定
                oldtime= nowtime;
                nowtime= timeGetTime();
                SetupMatrices();
                //背景の描画
                FrameMove();
                //頂点フォーマットの設定
                g_pDEV->SetFVF(D3DFVF_CUSTVERTEX);
                //直接データを渡して描画
                g_pDEV->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,2,vtx,sizeof(D3D_CUSTVERTEX));
                //メッシュを描画
                FrameMove1();
                for(i=0; i<g_Num1; i++)
                {   g_pDEV->SetMaterial(&g_pMat1[i]);
                    g_pDEV->SetTexture(0,g_pTex1[i]);
                    g_pMesh1->DrawSubset(i);     // Draw the mesh subset
                }
                FrameMove2();
                for(i=0; i<g_Num2; i++)
                {   g_pDEV->SetMaterial(&g_pMat2[i]);
                    g_pDEV->SetTexture(0,g_pTex2[i]);
                    g_pMesh2->DrawSubset(i);    // Draw the mesh subset
                }
                for(n=0; n<10; n++)
                {   if (flag[n])
                    {   FrameMove3(n);
                        for(i=0; i<g_Num3; i++)
                        {   g_pDEV->SetMaterial(&g_pMat3[i]);
                            g_pDEV->SetTexture(0,g_pTex3[i]);
                            g_pMesh3->DrawSubset(i);    // Draw the mesh subset
                        }
                    }
                }
                //着弾アニメーション
                if (bomb_c)
                {   FrameMoveBomb();
                    g_pDEV->SetFVF(D3DFVF_CUSTVERTEX);
                    g_pDEV->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP,2,vtbomb,sizeof(D3D_CUSTVERTEX));
                }
                g_pDEV->EndScene();
            }
            g_pDEV->Present(NULL,NULL,NULL,NULL);
        }
        

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

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

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