admin 管理员组文章数量: 1086019
D2D RPG游戏开发日记(一)
主要是作为自己做的2DRPG游戏日记 采用direct2D vs2015 c++ win32 还在开发中 预计写到3月底应该
简述:
本项目使用D2D API制作一款2DRPG游戏。暂定游戏设计有三个主角,6幅地图(1张城镇,5张迷宫),5幅战斗背景图,100个NPC
D2D如何渲染位图:
参见博客:.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中。
转载于:.html
本文标签: D2D RPG游戏开发日记(一)
版权声明:本文标题:D2D RPG游戏开发日记(一) 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/b/1693412795a220470.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论