シップが爆発するアニメーション



キーを押すとシップが爆発して消滅します。
シップの画像と爆発の画像と効果音を組み合わせます。
C#でも アニメーションクラス を作成しています。

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

プログラムの説明

  1. WAVE を鳴らすので mmsystem.h を取り込んで、winmm.lib をリンクします。
    ID_TIMER でアニメーションを描画するタイミングを設定します。
    g_Anime はアニメーションを制御する変数です。
    g_Ship はシップを描画するフラグです。
    Box で再描画する矩形領域を設定します。
        #include    <mmsystem.h>
        #include    "sprite.h"
        #pragma     comment(lib,"winmm.lib")
        #define     SAFE_DELETE(p)  { if (p) { delete (p);     (p)=NULL; } }
        #define     SAFE_RELEASE(p) { if (p) { (p)->Release(); (p)=NULL; } }
        #define     ID_TIMER    32767
    
        SPRITE      *Bomb= NULL;    //爆発アニメーション
        SPRITE      *Ship= NULL;    //Ship SPRITE Class
        int         g_Anime= 0;     //爆発アニメーションの進度
        int         g_Ship= 1;      //Ship の描画フラグ
        RECT        Box= { 100,60,260,220 };
        
  2. WM_CREATE: で Object をインスタンス化して画像を入力します。
    アニメーションの画像(bomb.bmp)は、4*4の16枚で構成されています。
    アニメーションを描画する速度をタイマで設定します。
            case WM_CREATE:
                Bomb= new SPRITE(hWnd);
                Bomb->Load("bomb.bmp",4,4);
                Ship= new SPRITE(hWnd);
                Ship->Load("ship.bmp",4,1);
                SetTimer(hWnd,ID_TIMER,200,NULL);
                break;
        
  3. WM_PAINT: では g_Ship のフラグがONのときシップを描画します。
    g_Anime は爆発画像のアニメーションを制御する変数です。
    この値は最初16に設定され、0番目~15番目の Sprite を順に切り替えて描画します。
    g_Anime が8のタイミングでシップの描画を停止します。
    アニメーションが終わると2000ミリ秒の時間を待って、最初の状態に戻します。
            case WM_PAINT:
                hdc= BeginPaint(hWnd,&ps);
                if (g_Ship)     Ship->Show(2,150,100);
                if (g_Anime)
                {   g_Anime--;
                    Bomb->Show(15-g_Anime,(WORD)Box.left,(WORD)Box.top);
                    if (g_Anime>=8) g_Ship= 0;
                    if (g_Anime==0)
                    {   Sleep(2000);    g_Ship= 1;  }
                }
                EndPaint(hWnd, &ps);
                break;
        
  4. WM_KEYDOWN: ではキーのダウン(種類は問わない)がポストされたときアニメーションを開始します。
    このとき爆発音(WAVE)を鳴らしますが、効果音が無いゲームプログラムは気の抜けたビールのような物で、 シューティングゲームには効果音は必須です。
            case WM_KEYDOWN:
                if (g_Anime==0)
                {   g_Anime= 16;
                    PlaySound("bomb.wav",NULL,SND_FILENAME | SND_ASYNC);
                }
                break;
        
  5. WM_TIMER: では InvalidateRect() で画面の再描画を設定するだけです。
            case WM_TIMER:
                InvalidateRect(hWnd,&Box,TRUE);
                break;
        
  6. WM_DESTROY: ではタイマを止めて Object を開放して下さい。
            case WM_DESTROY:
                KillTimer(hWnd,ID_TIMER);
                SAFE_DELETE(Bomb);
                SAFE_DELETE(Ship);
                PostQuitMessage(0);
                return 0L;
        

【当たり判定】

自機(敵機)や弾丸の画像は矩形で描画されますが、当たり判定では矩形範囲の交差を厳密に判定しても意味はありません。
シューティングゲームの当たり判定は、ゲームをプレイした感覚で決めるのがベストです。
従って当たり判定は、矩形範囲(自機,敵機)に点(弾)が入ったか否かで判定するのが簡単です。
このとき注意しなければならないことは、弾が機体の真ん中を通過しているのに当たり判定が利かない場合があることです。
当たり判定はタイマ割り込みなどでチェックするので、前回のチェックと今回のチェックの間に弾が通過してしまうことがあります。
これをカバーするために、弾の進行方向に向けて矩形範囲を広げてやります。

機体の中心から円を描いて、その中に弾丸が入れば、ヒットとする方法が実用的でしょうか。
前田稔(Maeda Minoru)の超初心者のプログラム入門 から「超初心者のプログラム入門(XNA(C#) game program)/当たり判定と爆発」を参照して下さい。

超初心者の方のために全ソースコードを掲載します。 (^_^;)
ファイル名 ファイルの説明 リンク
Bomb.cpp ソースプログラム

超初心者のプログラム入門(Win32API C++)