BGMAP のイメージ画像を生成する

BG の画像

CreateCompatibleBitmap で画像メモリを確保して、BGMAP のイメージ画像を直接生成して DOT 単位にスクロールします。
メモリに余裕のあるパソコンならではの手法で、携帯やコンシューマでは使えませんが、BG を表示する最も簡単な方法です。

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

プログラムの説明

  1. 宣言と Global Area の定義です。
    MyD3D Object Class には DirectX の SPRITE とは別に、私が作成した Sprite 機能がインプリメントされています。
    これを使えば、簡単に BG を描画することができます。
    *myd3d は MyD3D Object Class の定義です。
    g_D3DPP はウインドウサイズを変更したときに画像が伸縮しないように設定する領域です。
    ImgFile[] が Mapchip 画像ファイルの名前で GIF 画像を使っています。
    DirectX では JPEG が標準でサポートされているのですが、JPEG は透明色には向きません。
    MapFile[] は BGMAP を構成する Mapchip の並び情報が記述された TEXT 形式のファイルです。
    このファイルは専用のツール(MapEdit)を使って作成しました。
    WINW, WINH はウインドウのサイズで、自由にリサイズすることが出来ます。
    XN,YN は背景画像(BGMAP)の大きさで、横と縦に並べる Chip の枚数で指定します。(16倍するとピクセルサイズ)
    XP,YP はドット単位に BG をスクロールする値で、矢印キーで操作します。
    *MAP は MapFile[] に記述された Mapchip の並び情報を二進数で格納する領域のポインタです。
    hMap,hMapDC は Mapchip 画像と *MAP の並び情報に基づいて作成した BGMAP の Surface です。
        /*************************************************/
        /*★ MyD3D Object Class  BackGround    前田 稔 ★*/
        /*************************************************/
        #define     NAME    "BackGround"
        #include    "MyD3D.h"
    
        // Global Area
        MyD3D                   *myd3d          = NULL;     // MyD3D Object Class
        HWND                    g_hWnd          = NULL;     // Windows Handle
        LPDIRECT3DDEVICE9       g_pDEV          = NULL;     // Direct3DDeviceインターフェイス
        D3DPRESENT_PARAMETERS   g_D3DPP;                    // D3DDeviceの設定
        bool                    g_bActive       = false;    // アクティブ状態
        char                    ImgFile[]       = "MapS.gif";
        char                    MapFile[]       = "Double.csv";
        int                     WINW= 640, WINH=480; 
        int                     XN=60,YN=50;    //背景のサイズ(XN*16) (YN*16)
        int                     XP,YP;
        int                     *MAP;           //BG Map Table
        HBITMAP                 hMap= NULL;     //BG Map の HBITMAP
        HDC                     hMapDC= NULL;   //BG Map の HDC
        
  2. WinMain() は「Map Chip で背景を表示」と同じです。
  3. WinMain() から呼ばれる DirectX を初期化する関数です。
    MyD3D Class を生成して DirectX を初期化し、Mapchip 画像をロードします。
    MyD3D Object Class には私が作成した Sprite 機能がインプリメントされています。
    Sprite の設定が出来たら Mapchip の並び情報を入力する SetMapTable() をコールします。
        // DirectX Graphics 初期化
        HRESULT  InitDXGraphics(void)
        {
            myd3d= new MyD3D(g_hWnd);
            myd3d->InitD3D(&g_pDEV);
            g_D3DPP= myd3d->D3DPPWin;
            myd3d->LoadFile(ImgFile);
            myd3d->SetSize(16,16);
            SetMapTable(MapFile);
            return S_OK;
        }
        
  4. Mapchip の並び情報を入力して背景画像(BGMAP)を生成する関数です。
    並び情報を格納する領域(*MAP)は、ダイナミックに割り当てています。
    SetTable() が TEXT 形式のファイルを入力して並び情報を格納する関数です。
    背景画像(BGMAP)用の Surface を確保して CreatImage() で BGMAP を生成します。
        // Set BG Map Table
        HRESULT  SetMapTable(LPSTR Maptxt)
        {   HDC     hDC;
    
            if (myd3d->hBmpDC==NULL)    return FALSE;
            MAP= new int[XN*YN];
            SetTable(Maptxt,MAP,XN*YN);
            // BG Map 用の Surface を作成
            hDC= GetDC(g_hWnd);
            hMapDC = CreateCompatibleDC(hDC);
            hMap = CreateCompatibleBitmap(hDC,XN*16,YN*16);
            SelectObject(hMapDC,hMap);
            ReleaseDC(g_hWnd,hDC);
            CreatImage();
            return  S_OK;
        }
        
  5. TEXT 形式のファイルを入力して並び情報を格納する関数です。
    g_buf をアロケートして TEXT 形式のファイルを入力します。
    SetInt() で TEXT 形式を二進数に変換して *MAP に格納します。
        // Set Binary Table
        HRESULT  SetTable(LPSTR szTxt, int tbl[], int n)
        {   char    *g_buf;
            HANDLE  hFile;
            DWORD   dwBytes;
    
            hFile = CreateFile(szTxt,GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
            if (hFile==INVALID_HANDLE_VALUE)
            {   MessageBox(NULL,szTxt,"Open File Error", MB_OK);
                return S_FALSE;
            }
            dwBytes= GetFileSize(hFile,NULL);
            g_buf= new char[dwBytes];
            SetFilePointer(hFile,0,0,FILE_BEGIN);
            ReadFile(hFile,g_buf,dwBytes,&dwBytes,NULL);
            CloseHandle(hFile);
            myd3d->SetInt(tbl,g_buf,n);
            delete [] g_buf;
            return  S_OK;
        }
        
  6. Surface に BGMAP を生成しています。
    メモリ上に背景画像全体を直接生成すると、プログラムが簡単になります。
    myd3d->Show() で Sprite 番号を指定してセルを一個ずつ hMapDC に描画します。
        // hMapDC(hMap) に背景画像を生成する
        HRESULT  CreatImage()
        {   int     x,y,idx;
    
            if (hMapDC==NULL || MAP==NULL)  return FALSE;
            for(y=0; y<YN; y++)
                for(x=0; x<XN; x++)
                {   idx= *(MAP+y*XN+x);
                    myd3d->Show(hMapDC,idx,x*16,y*16);
                }
            return  S_OK;
        }
        
  7. BGMAP を描画する Draw() 関数です。
    矢印キーで XP,YP を操作して BGMAP をスクロールします。
    Surface に BGMAP 全体の画像が生成できているので描画は簡単です。
    WINW, WINH にウインドウサイズが格納されているので、BGMAP をウインドウに合わせて描画します。
        // 画面の描画処理
        HRESULT Draw(void)
        {   HDC         hDC;
            int         win_w,win_h;
    
            if (!g_pDEV || !g_bActive)  return false;
            if (GetAsyncKeyState(VK_ESCAPE)<0)      //ESC キー
            {   PostMessage(g_hWnd,WM_CLOSE,0,0);
                return FALSE;
            }
            if (GetAsyncKeyState(VK_UP)<0 && YP>1)      YP-= 2;
            if (GetAsyncKeyState(VK_DOWN)<0)            YP+= 2;
            if (GetAsyncKeyState(VK_LEFT)<0 && XP>1)    XP-= 2;
            if (GetAsyncKeyState(VK_RIGHT)<0)           XP+= 2;
    
            g_pDEV->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(150,150,150),1.0f,0);
            hDC= myd3d->GetBackDC();
            if (hDC==NULL)
            {   MessageBox(NULL,"GetBackBuffer Error","Error Message", MB_OK);
                return FALSE;
            }
            // BackSurface に直接描画
            win_w= WINW;
            win_h= WINH;
            if (XN*16-XP<WINW)   win_w= XN*16-XP;
            if (YN*16-YP<WINH)   win_h= YN*16-YP;
            TransparentBlt(hDC,0,0,win_w,win_h,hMapDC,XP,YP,win_w,win_h,RGB(0,0,0));
            myd3d->ReleaseBackDC(hDC);
            return g_pDEV->Present(NULL, NULL, NULL, NULL);
        }
        
  8. WM_SIZE: では画像が伸縮しないように処理して下さい。
            case WM_SIZE:
                if (!g_pDEV || wParam == SIZE_MINIMIZED)    break;
                g_D3DPP.BackBufferWidth  = LOWORD(lParam);
                g_D3DPP.BackBufferHeight = HIWORD(lParam);
                if (wParam==SIZE_MAXIMIZED || wParam==SIZE_RESTORED)  ChangeWindowSize();
                break;
        
  9. WM_DESTROY: では使用したリソースを開放しています。
            case WM_DESTROY:
                SAFE_DELDC(hMapDC);
                SAFE_DELOBJ(hMap);
                SAFE_DELETE(myd3d);
                PostQuitMessage(0);
                g_hWnd = NULL;
                return 0;
        

超初心者の方のために全ソースコードを掲載します。 (^_^;)
全ソースコード

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

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

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