キー操作で BMP 画像を動かす



GetKeyboardState() で矢印キーの状態を調べて BMP 画像を動かします。
WM_KEYDOWN: でポストされたキーコードを検出する方法は、応答速度やリピート機能などの点でゲームには向きません。

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

プログラムの説明です。

  1. 新規プロジェクト(BmpMove)を作成してソースプログラムの最初の部分を表示して下さい。
    BMP 画像を表示する座標を記録する領域を定義します。
        int     XPOS=100, YPOS=50;          // 描画する座標
        
  2. BMP 画像を入力して XPOS,YPOS の座標に表示する関数です。
        //★ BMP ファイルを表示する
        HRESULT ViewBMP(HDC hdc)
        {   HBITMAP     hbmp;
            BITMAP      bmp;
            HDC         hMdc;
    
            hbmp= (HBITMAP)LoadImage(NULL,"Enemy08.bmp",IMAGE_BITMAP,0,0,
                                     LR_LOADFROMFILE|LR_CREATEDIBSECTION);
            if (hbmp==NULL)
            {   MessageBox(NULL,"Enemy08.bmp","Load BMP Error",MB_OK);
                return  E_FAIL;
            }
    
            hMdc= CreateCompatibleDC(hdc);
            SelectObject(hMdc, hbmp);
            GetObject(hbmp,sizeof(BITMAP),&bmp);
            BitBlt(hdc,XPOS,YPOS,bmp.bmWidth,bmp.bmHeight,hMdc,0,0,SRCCOPY);
            DeleteObject(hbmp);
            DeleteDC(hMdc);
            return TRUE;
        }
        
  3. キーをセンスして矢印キー状態を取得して座標を設定する関数です。
    ESC キーが押されるとプログラムを終了します。
    矢印キーが押されると座標を移動して InvalidateRect() で画面を再描画します。
    Y座標の移動では TRUE を、X座標の移動では FALSE を使っていることに注目して下さい。
    TRUE を使うと画面全体がクリアされるため、チラツキが目立ちます。
    但し、FALSE を使うと現在描画中の画面の上から描画されるため、描画されない部分がそのまま残ります。
    画面の背景を規定値(白)に戻して確かめて下さい。
    FALSE を設定しても多少はチラツキが残ります。
    完全にチラツキを無くすには DirectX を使うことになります。
        void KeyCheck(HWND hwnd)
        {   BYTE    KeyBuffer[256];
            BOOL    state;
    
            // キーボードの状態を読み取る
            GetKeyboardState(KeyBuffer);
            if (KeyBuffer[VK_ESCAPE]&0xf0)              //ESC
            {   PostMessage(hwnd,WM_CLOSE,0,0);         //WM_CLOSE をポスト
                return;
            }
            if (KeyBuffer[VK_UP]&0xf0)      {  YPOS--; InvalidateRect(hwnd,NULL,TRUE);  }
            if (KeyBuffer[VK_DOWN]&0xf0)    {  YPOS++; InvalidateRect(hwnd,NULL,TRUE);  }
            if (KeyBuffer[VK_LEFT]&0xf0)    {  XPOS--; InvalidateRect(hwnd,NULL,FALSE);  }
            if (KeyBuffer[VK_RIGHT]&0xf0)   {  XPOS++; InvalidateRect(hwnd,NULL,FALSE);  }
        }
        
  4. 画面の背景色を黒に設定して下さい。
        //wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
        wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+2);
        
  5. CALLBACK WndProc() を表示して下さい。
    BMP 画像を描画する関数を呼びます。
            case WM_PAINT:
                hdc = BeginPaint (hWnd, &ps);
                // TODO: この位置に描画用のコードを追加してください...
                ViewBMP(hdc);
                EndPaint( hWnd, &ps );
                break;
        
  6. WinMain() を表示して下さい。
    今回のように直接キーをセンスするときは TranslateMessage() は不要です。
    別にコメントにする必要は無いのですが削除しても動くことを確かめて下さい。
        // メイン メッセージ ループ:
        while( GetMessage(&msg, NULL, 0, 0) ) 
        {
            if( !TranslateAccelerator (msg.hwnd, hAccelTable, &msg) ) 
            {
                //TranslateMessage( &msg );
                DispatchMessage( &msg );
            }
            KeyCheck(msg.hwnd);
        }
        
  7. [デバッグ][デバッグなしで開始]を選択して、ビルドに続いて実行を行います。
    上下左右の矢印キーで画像が動くことを確かめて下さい。

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