犬が歩くアニメーションを描画する

犬のアニメーション

VC++ でタイマ割り込みを使って画像を切り替えながら犬が歩くアニメーションを描画します。
2014/10/04 Windows8.1 & .NET2005 で再コンパイルします。

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

プロジェクトの設定

  1. 新規プロジェクト(Main)を作成して my.lib と my.h をフォルダーに格納して下さい。
    my.h 私有 Object Class Library のヘッダーファイル
    my.lib 私有 Object Class Library のプログラムファイル
    私が提供した ★Object Class Library を使うときは Image Object Class を使って下さい。
  2. [プロジェクト] [既存項目の追加] から my.h をプロジェクトに追加します。
    [プロジェクト] [プロパティ] [リンカ] [入力] から追加する依存関係を編集して [my.lib] を追加します。
  3. ソースプログラムの先頭を表示して my.h を取り込んで下さい。
        #include    <windows.h>
        #include    "Main.h"
        #include    "my.h"
        
  4. プリコンパイルヘッダを使っているときの設定です。
    stdafx.h を表示して my.h を取り込んで下さい。
    #include "my.h"
  5. 「// グローバル変数 :」の位置までスクロールして下さい。
    次の表示を参考にして、ソースコードを追加して下さい。
        //#define     ID_TIMER    32767
        #define     ID_TIMER    (WM_APP + 0)
    
        // グローバル変数 :
        HINSTANCE hInst;                                // 現在のインターフェイス
        TCHAR szTitle[MAX_LOADSTRING];                  // タイトル バーのテキスト
        TCHAR szWindowClass[MAX_LOADSTRING];            // メイン ウィンドウ クラス名
    
        //BMP Object Area
        BMP         *Bmp[5]= { NULL,NULL,NULL,NULL,NULL };
        char         BMPID[5][12]=
        {  "IDB_BITMAP0",  "IDB_BITMAP1", "IDB_BITMAP2", "IDB_BITMAP3", "IDB_BITMAP4" }; 
        int          i;
        WORD         no= 4; 
        
  6. InitInstance() で画面のサイズを設定します。
    Windows の表示位置を 100,100 に、サイズを 200,150 に設定しています。
        BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
        {   HWND hWnd;
            hInst = hInstance; // グローバル変数にインスタンス処理を格納します。
    
            hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
         //          CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
                   100, 100, 200, 150, NULL, NULL, hInstance, NULL);
        
  7. WndProc() に WM_CREATE: を追加します。
    次の表示を参考にして、ソースコードを追加して下さい。
        LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
        {       :
                :
            case WM_CREATE:
                for(i=0; i<5; i++)
                {   Bmp[i]= new BMP(hWnd);
                    Bmp[i]->Load(BMPID[i]);
                }
                SetTimer(hWnd,ID_TIMER,200,NULL);
                break;
        
  8. WM_PAINT: を表示して下さい。
    次の表示を参考にして、ソースコードを追加して下さい。
        case WM_PAINT:
            hdc = BeginPaint(hWnd, &ps);
            // TODO: 描画コードをここに追加してください...
            no= no%5;
            Bmp[no]->Show(hdc);
            EndPaint(hWnd, &ps);
            break;
        
  9. WndProc() に WM_TIMER: を追加します。
    次の表示を参考にして、ソースコードを追加して下さい。
        case WM_TIMER:
            no++;
            InvalidateRect(hWnd,NULL,TRUE);
            UpdateWindow(hWnd); 
            break;
        
  10. WndProc() に WM_CLOSE: を追加します。
    次の表示を参考にして、ソースコードを追加して下さい。
        case WM_CLOSE:
            KillTimer(hWnd,ID_TIMER);
            for(i=0; i<5; i++)   SAFE_DELETE(Bmp[i]);
            DestroyWindow(hWnd);
            break;
        
  11. BMP 画像をリソースとして取り込みます。
    アニメーション用の画像「dog0.bmp ~ dog4.bmp」の画像を取り込んで下さい。
    BITMAP の ID(IDB_BITMAP0~IDB_BITMAP4) の両側を "" で囲って下さい。
    Visual C++ Ver 6.0 ではフルカラー画像のプレビューは表示されません。
    BMP リソースの取り込みは BMP 画像を表示する を参照して下さい。
  12. [デバッグ]を選択してビルドに続いて実行を行います。
    ページ先頭の画面が表示されて犬のアニメーションが動いていれば完成です。

プログラムの説明

  1. #define で ID_TIMER を定義します。
    ID_TIMER には、プログラムで使われている「他のIDと重ならないように適当な値」を設定します。
    値は何でも良いのですが (WM_APP + 0) のように定義する方法が推奨されています。
    犬のアニメーションに使う領域を定義しています。
    BMP Bmp[5] はアニメーションに使う5枚の画像 Object です。
    BMPID[5][12] はリソースに取り込んだ BMP の ID です。
    WORD は unsigned short と同じです。 no は表示する画像の番号です。
        //#define     ID_TIMER    32767
        #define     ID_TIMER    (WM_APP + 0)
    
        // グローバル変数 :
        HINSTANCE hInst;                                // 現在のインターフェイス
        TCHAR szTitle[MAX_LOADSTRING];                  // タイトル バーのテキスト
        TCHAR szWindowClass[MAX_LOADSTRING];            // メイン ウィンドウ クラス名
    
        //BMP Object Area
        BMP         *Bmp[5]= { NULL,NULL,NULL,NULL,NULL };
        char         BMPID[5][12]=
        {  "IDB_BITMAP0",  "IDB_BITMAP1", "IDB_BITMAP2", "IDB_BITMAP3", "IDB_BITMAP4" }; 
        int          i;
        WORD         no= 4; 
        
  2. InitInstance() で画面のサイズを設定します。
    Windows の表示位置を 100,100 にサイズを 200,150 に設定しています。
        BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
        {   HWND hWnd;
            hInst = hInstance; // グローバル変数にインスタンス処理を格納します。
    
            hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
         //          CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
                   100, 100, 200, 150, NULL, NULL, hInstance, NULL);
        
  3. WndProc() に WM_CREATE: を追加します。
    BMP Object Class をインスタンス化してリソースで取り込んだ画像をロードします。
    SetTimer() で 200 ミリセコンドごとにタイマを設定します。
    この値でアニメーションの速度が変わります。
        LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
        {       :
                :
            case WM_CREATE:
                for(i=0; i<5; i++)
                {   Bmp[i]= new BMP(hWnd);
                    Bmp[i]->Load(BMPID[i]);
                }
            SetTimer(hWnd,ID_TIMER,200,NULL);
            break;
        
  4. WM_PAINT に画像を表示するコードを追加します。
    no はタイマ割り込みの度にインクリメントされ 0~4 を繰り返します。
    Bmp[no]->Show(hdc) で no の画像を表示します。
            case WM_PAINT:
            hdc = BeginPaint(hWnd, &ps);
            // TODO: 描画コードをここに追加してください...
            no= no%5;
            Bmp[no]->Show(hdc);
            EndPaint(hWnd, &ps);
            break;
        
  5. タイマ割り込みの処理です。
    アニメーション画像を切り替えるために no をインクリメントします。
    画面を再表示するために InvalidateRect() と UpdateWindow() を実行します。
    UpdateWindow() が実行されると WM_PAINT が呼ばれます。
        case WM_TIMER:
            no++;
            InvalidateRect(hWnd,NULL,TRUE);
            UpdateWindow(hWnd); 
            break;
        
  6. WM_CLOSE: で終了処理を行います。
    タイマ割り込みを停止して、BMP Object Class を開放します。
    DestroyWindow(hWnd) で Windows アプリケーションを終了します。
        case WM_CLOSE:
            KillTimer(hWnd,ID_TIMER);
            for(i=0; i<5; i++)   SAFE_DELETE(Bmp[i]);
            DestroyWindow(hWnd);
            break;
        

【演習】

  1. 下記の画像を使って各自で作成してみて下さい。
  2. BMP Object Class の定義です。
        //BMP Object Class の定義
        BMP         *Bmp[5]= { NULL,NULL,NULL,NULL,NULL };
    
        //リソースで取り込んだ画像を表示する場合
        char         BMPID[5][12]=
        {  "IDB_BITMAP0",  "IDB_BITMAP1", "IDB_BITMAP2", "IDB_BITMAP3", "IDB_BITMAP4" }; 
    
        //画像をファイルから直接入力する場合
        char         BMPID[5][12]=
        {  "dog0.bmp",  "dog1.bmp", "dog2.bmp", "dog3.bmp", "dog4.bmp" }; 
        
  3. Image Object Class のソースコードは ★Object Class Library から取得することが出来ます。
    次のファイルをプロジェクトのフォルダーに格納して下さい。
    main.cpp 説明した Main プログラムファイル
    image.h Image Object Class のヘッダーファイル
    image.cpp Image Object Class のプログラムファイル

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