D2D RPG游戏开发日记(一)--准备

2018-06-17 23:17:58来源:未知 阅读 ()

新老客户大回馈,云服务器低至5折

  主要是作为自己做的2DRPG游戏日记 采用direct2D vs2015 c++ win32 还在开发中 预计写到3月底应该

  简述:

本项目使用D2D API制作一款2DRPG游戏。暂定游戏设计有三个主角,6幅地图(1张城镇,5张迷宫),5幅战斗背景图,100个NPC

D2D如何渲染位图:

参见博客:http://www.cnblogs.com/graphics/archive/2011/05/23/1964273.html

第零步:C++Win32程序基本结构

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)  
2.    {  
3.        switch (message)  
4.        {  
5.        case   WM_PAINT:   //Draw  
6.            if (!pRenderTarget)  
7.            {  
8.                CreateResource(hwnd);  
9.                Form_Load();  
10.            }  
11.            else  
12.            {  
13.                Begindraw();  
14.                DrawMap(hwnd, pRenderTarget,map, player,npc,current_player,current_map, animation_ctrl);  
15.                Enddraw();  
16.            }  
17.      
18.            return 0;  
19.      
20.        case WM_KEYDOWN:  
21.        {  
22.              
23.            end = GetTickCount();  
24.            if (end - start > player[current_player].walk_interval)  
25.            {  
26.                start = end;  
27.                animation_ctrl++;  
28.                key_ctrl(hwnd, wParam, player, ¤t_player,map,¤t_map,npc);  
29.            }  
30.        }  
31.        break;  
32.      
33.        case WM_DESTROY:  
34.            Cleanup();  
35.            PostQuitMessage(0);  
36.            return 0;  
37.        }  
38.      
39.        return DefWindowProc(hwnd, message, wParam, lParam);  
40.    }  
41.      
42.    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)  
43.    {  
44.      
45.        WNDCLASSEX winClass;  
46.      
47.        winClass.lpszClassName = "Direct2D";  
48.        winClass.cbSize = sizeof(WNDCLASSEX);  
49.        winClass.style = CS_HREDRAW | CS_VREDRAW;  
50.        winClass.lpfnWndProc = WndProc;  
51.        winClass.hInstance = hInstance;  
52.        winClass.hIcon = NULL;  
53.        winClass.hIconSm = NULL;  
54.        winClass.hCursor = LoadCursor(NULL, IDC_ARROW);  
55.        winClass.hbrBackground = NULL;  
56.        winClass.lpszMenuName = NULL;  
57.        winClass.cbClsExtra = 0;  
58.        winClass.cbWndExtra = 0;  
59.      
60.        if (!RegisterClassEx(&winClass))  
61.        {  
62.            MessageBox(NULL, TEXT("This program requires Windows NT!"), "error", MB_ICONERROR);  
63.            return 0;  
64.        }  
65.      
66.        HWND hwnd = CreateWindowEx(NULL,  
67.            "Direct2D",                 // window class name  
68.            "寻仙传",            // window caption  
69.            WS_MAXIMIZE,        // window style  
70.            CW_USEDEFAULT,              // initial x position  
71.            CW_USEDEFAULT,              // initial y position  
72.            640,                        // initial x size  
73.            480,                        // initial y size  
74.            NULL,                       // parent window handle  
75.            NULL,                       // window menu handle  
76.            hInstance,                  // program instance handle  
77.            NULL);                      // creation parameters  
78.      
79.        ShowWindow(hwnd, iCmdShow);  
80.        UpdateWindow(hwnd);  
81.      
82.        MSG    msg;  
83.        ZeroMemory(&msg, sizeof(msg));  
84.      
85.        while (GetMessage(&msg, NULL, 0, 0))  
86.        {  
87.            TranslateMessage(&msg);  
88.            DispatchMessage(&msg);  
89.        }  
90.      
91.        return msg.wParam;  
92.    }  

第一步:创建D2D工厂,画布,WIC工厂

1.    VOID CreateResource(HWND hWnd)  
2.    {  
3.        HRESULT hr;  
4.        //创建D2D工厂  D2D1CreateFactory 
5.        hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &pD2DFactory);  
6.        if (FAILED(hr))  
7.        {  
8.            MessageBox(hWnd, "Create D2D factory failed!", "Error", 0);  
9.            return;  
10.        }  
11.      
12.        // Obtain the size of the drawing area  
13.        RECT rc;  
14.        GetClientRect(hWnd, &rc);  
15.      
16.        // Create a Direct2D render target  
17.        hr = pD2DFactory->CreateHwndRenderTarget(  
18.            D2D1::RenderTargetProperties(),  
19.            D2D1::HwndRenderTargetProperties(  
20.                hWnd,  
21.                D2D1::SizeU(rc.right - rc.left, rc.bottom - rc.top)  
22.            ),  
23.            &pRenderTarget  
24.        );  
25.        if (FAILED(hr))  
26.        {  
27.            MessageBox(hWnd, "Create render target failed!", "Error", 0);  
28.            return;  
29.        }  
30.      
31.        // Create WIC factory 用于加载位图 
32.        hr = CoCreateInstance(  
33.                    CLSID_WICImagingFactory1,  
34.                        NULL,  
35.                        CLSCTX_INPROC_SERVER,  
36.                        IID_IWICImagingFactory,  
37.                        reinterpret_cast<void **>(&pWICFactory)  
38.                    );  
39.        if (FAILED(hr))  
40.        {  
41.            MessageBox(hWnd, "Create render target failed!", "Error", 0);  
42.            return;  
43.        }  
44.    }  

第二步:使用WIC从文件中加载位图到ID2D1Bitmap

1.    HRESULT LoadBitmapFromFile(  
2.        ID2D1RenderTarget *pRenderTarget,  
3.        IWICImagingFactory *pIWICFactory,  
4.        PCWSTR uri,  // 文件的路径 
5.        UINT destinationWidth,  
6.        UINT destinationHeight,  
7.        ID2D1Bitmap **ppBitmap  
8.    )  
9.    {  
10.        HRESULT hr = S_OK;  
11.      
12.        IWICBitmapDecoder *pDecoder = NULL;  
13.        IWICBitmapFrameDecode *pSource = NULL;  
14.        IWICStream *pStream = NULL;  
15.        IWICFormatConverter *pConverter = NULL;  
16.        IWICBitmapScaler *pScaler = NULL;  
17.      
18.        hr = pIWICFactory->CreateDecoderFromFilename(  
19.            uri,  
20.            NULL,  
21.            GENERIC_READ,  
22.            WICDecodeMetadataCacheOnLoad,  
23.            &pDecoder  
24.        );  
25.        if (SUCCEEDED(hr))  
26.        {  
27.      
28.            // Create the initial frame.  
29.            hr = pDecoder->GetFrame(0, &pSource);  
30.        }  
31.      
32.        if (SUCCEEDED(hr))  
33.        {  
34.            // Convert the image format to 32bppPBGRA  
35.            // (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED).  
36.            hr = pIWICFactory->CreateFormatConverter(&pConverter);  
37.        }  
38.        if (SUCCEEDED(hr))  
39.        {  
40.            // If a new width or height was specified, create an  
41.            // IWICBitmapScaler and use it to resize the image.  
42.            if (destinationWidth != 0 || destinationHeight != 0)  
43.            {  
44.                UINT originalWidth, originalHeight;  
45.                hr = pSource->GetSize(&originalWidth, &originalHeight);  
46.                if (SUCCEEDED(hr))  
47.                {  
48.                    if (destinationWidth == 0)  
49.                    {  
50.                        FLOAT scalar = static_cast<FLOAT>(destinationHeight) / static_cast<FLOAT>(originalHeight);  
51.                        destinationWidth = static_cast<UINT>(scalar * static_cast<FLOAT>(originalWidth));  
52.                    }  
53.                    else if (destinationHeight == 0)  
54.                    {  
55.                        FLOAT scalar = static_cast<FLOAT>(destinationWidth) / static_cast<FLOAT>(originalWidth);  
56.                        destinationHeight = static_cast<UINT>(scalar * static_cast<FLOAT>(originalHeight));  
57.                    }  
58.      
59.                    hr = pIWICFactory->CreateBitmapScaler(&pScaler);  
60.                    if (SUCCEEDED(hr))  
61.                    {  
62.                        hr = pScaler->Initialize(  
63.                            pSource,  
64.                            destinationWidth,  
65.                            destinationHeight,  
66.                            WICBitmapInterpolationModeCubic  
67.                        );  
68.                    }  
69.                    if (SUCCEEDED(hr))  
70.                    {  
71.                        hr = pConverter->Initialize(  
72.                            pScaler,  
73.                            GUID_WICPixelFormat32bppPBGRA,  
74.                            WICBitmapDitherTypeNone,  
75.                            NULL,  
76.                            0.f,  
77.                            WICBitmapPaletteTypeMedianCut  
78.                        );  
79.                    }  
80.                }  
81.            }  
82.            else // Don't scale the image.  
83.            {  
84.                hr = pConverter->Initialize(  
85.                    pSource,  
86.                    GUID_WICPixelFormat32bppPBGRA,  
87.                    WICBitmapDitherTypeNone,  
88.                    NULL,  
89.                    0.f,  
90.                    WICBitmapPaletteTypeMedianCut  
91.                );  
92.            }  
93.        }  
94.        if (SUCCEEDED(hr))  
95.        {  
96.            // Create a Direct2D bitmap from the WIC bitmap.  
97.            hr = pRenderTarget->CreateBitmapFromWicBitmap(  
98.                pConverter,  
99.                NULL,  
100.                ppBitmap  
101.            );  
102.        }  
103.      
104.        SAFE_RELEASE(pDecoder);  
105.        SAFE_RELEASE(pSource);  
106.        SAFE_RELEASE(pStream);  
107.        SAFE_RELEASE(pConverter);  
108.        SAFE_RELEASE(pScaler);  
109.      
110.        return hr;  
111.    }  

第三步:开始绘图,结束绘图,释放资源函数

1.    VOID Begindraw()  
2.    {  
3.        pRenderTarget->BeginDraw();  
4.    }  
5.    VOID Enddraw()  
6.    {  
7.        HRESULT hr = pRenderTarget->EndDraw();  
8.        if (FAILED(hr))  
9.        {  
10.            MessageBox(NULL, "Draw failed!", "Error", 0);  
11.      
12.            return;  
13.        }  
14.    }  
15.    VOID Cleanup()  
16.    {  
17.        SAFE_RELEASE(pWICFactory);  
18.        SAFE_RELEASE(pRenderTarget);  
19.        SAFE_RELEASE(pD2DFactory);  
20.    }  

第四步:绘图函数

1.    pRenderTarget->DrawBitmap(  
2.                map[current_map].map,  
3.                window_size,// D2D1_SIZE_ F格式窗口大小  
4.                1.0f,  
5.                D2D1_BITMAP_INTERPOLATION_MODE_LINEAR,  
6.                map_size  // D2D1_SIZE_ F格式要显示的位图区域  
7.            );  

将绘图函数放到begindraw与enddraw之间,几个函数放置在WndProc函数W的IN_PAIN中。

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:字符串替换For linux C

下一篇:QT编写TCP入门+简单的实际项目(附源程序)