• 【MFC】打砖块小游戏(中)(6)


    整理代码:

    将前述的两个函数整理到新建SDK3_API.h 和  SDK3_API.cpp 中。注意头文件的包含 和 使用外部变量引用 HINSTANCE hInst;    

    动画的实现

    设计思路:启动定时,修改球的位置,实现WM_TIMER  消息的处理。

    首先,定义变量 :球位置(X,Y 坐标),球的速度(CX,CY),挡板的位置(X 即可,为了统一可以设置两个坐标)

    然后,响应菜单命令(菜单命令 WM_COMMAND 消息,通过id来区分菜单命令的发送方),启动定时器

    定时器函数中,修改球的位置(加水平 和 垂直方向的速度),重新绘制界面。

    为了避免界面闪烁,以及统一对前一个界面的清除,使用 缓存DC。

    核心代码如下:

    1、消息处理函数中,添加对启动命令的处理:

     2、在添加的  SDK3_API.cpp 中定义变量

     其中,tempBitmap 和 hTempDC 是为了实现 缓存 DC功能 (仅兼容DC无法实现对显示DC的缓存,还需要一张与显示窗口大小一样的空白图片)

    下面的 int 变量分别是球、挡板的位置,以及球的速度(垂直方向为负,往上);

    另外,球的速度可以减少一点,定时间隙设置小一点,球的动画效果看起来会更连续。

    3、实现定时处理函数

     其实完全可以在窗口函数中,实现对WM_TIMER消息进行处理

    ::SetTimer(hWnd,1,1000,NULL); 第2个参数是定时的ID,可能多个定时。第四个参数不指定定时处理函数,则在窗口函数的WM_TIMER进行处理。

    4、修改Draw函数,实现缓存

    5、当然,初始化函数中需要对新建的缓存DC和图片进行处理

     

     代码:

    SDK3_API.h

    1. #pragma once
    2. void Init(HWND hWnd);
    3. void Draw(HDC hdc );
    4. void WINAPI TimerProc(HWND, UINT, UINT, DWORD);

    SDK3_API.cpp

    1. #include "stdafx.h"
    2. #include "SDK_3.h"
    3. #include "resource.h"
    4. #include "SDK3_API.h"
    5. extern HINSTANCE hInst;
    6. BYTE brick_array[4][10]={
    7. {0,1,1,1,1,1,1,1,1,0},
    8. {0,0,1,1,1,1,1,1,0,0},
    9. {0,0,0,1,1,1,1,0,0,0},
    10. {0,0,0,0,1,1,0,0,0,0}
    11. };
    12. HBITMAP ball,brick,baffle,tempBitmap;
    13. HDC hMemDC,hTempDC;
    14. int ballx=225,bally=420,bafflex=170,baffley=430,cx=2,cy=-2;
    15. void Init(HWND hWnd)
    16. {
    17. baffle = ::LoadBitmap(hInst,MAKEINTRESOURCE(IDB_BITMAP1));
    18. ball = ::LoadBitmap(hInst,MAKEINTRESOURCE(IDB_BITMAP2));
    19. brick = ::LoadBitmap(hInst,MAKEINTRESOURCE(IDB_BITMAP3));
    20. ::SetWindowPos(hWnd,
    21. NULL,
    22. (::GetSystemMetrics(SM_CXFULLSCREEN) - 450)/2,
    23. (::GetSystemMetrics(SM_CYFULLSCREEN) - 450)/2,
    24. 450,
    25. 500,
    26. SWP_NOZORDER);
    27. HDC hdc = ::GetDC(hWnd);
    28. hMemDC = ::CreateCompatibleDC(hdc);
    29. hTempDC=::CreateCompatibleDC(hdc);
    30. tempBitmap = ::CreateCompatibleBitmap(hdc,450,500);
    31. ::SelectObject(hTempDC,tempBitmap);
    32. ::ReleaseDC(hWnd,hdc);
    33. }
    34. void Draw(HDC hdc )
    35. {
    36. int i,j;
    37. ::PatBlt(hTempDC,0,0,450,500,WHITENESS);
    38. ::SelectObject(hMemDC,brick);
    39. for(i = 0; i < 4; i++)
    40. {
    41. for(j = 0; j < 10; j++)
    42. {
    43. if(brick_array[i][j] == 1)
    44. {
    45. ::BitBlt(hTempDC,j * 45,i * 20,45,20,hMemDC,0,0,SRCCOPY);
    46. }
    47. }
    48. }
    49. ::SelectObject(hMemDC,ball);
    50. ::BitBlt(hTempDC,ballx,bally,10,10,hMemDC,0,0,SRCCOPY);
    51. ::SelectObject(hMemDC,baffle);
    52. ::BitBlt(hTempDC,bafflex,baffley,111,10,hMemDC,0,0,SRCCOPY);
    53. ::BitBlt(hdc,0,0,450,500,hTempDC,0,0,SRCCOPY);
    54. }
    55. void WINAPI TimerProc(HWND hWnd, UINT nMsg,UINT nTimerid,DWORD dwTime)
    56. {
    57. if(nTimerid ==1)
    58. {
    59. ballx+=cx;
    60. bally+=cy;
    61. HDC hdc=::GetDC(hWnd);
    62. Draw(hdc);
    63. ::ReleaseDC(hWnd,hdc);
    64. }
    65. }

    SDK_3.cpp 主函数源文件

    1. // SDK_3.cpp : 定义应用程序的入口点。
    2. //
    3. #include "stdafx.h"
    4. #include "SDK_3.h"
    5. #include "SDK3_API.h"
    6. #define MAX_LOADSTRING 100
    7. // 全局变量:
    8. HINSTANCE hInst; // 当前实例
    9. TCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本
    10. TCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名
    11. // 此代码模块中包含的函数的前向声明:
    12. ATOM MyRegisterClass(HINSTANCE hInstance);
    13. BOOL InitInstance(HINSTANCE, int);
    14. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    15. INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
    16. bool isStart=false;
    17. int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
    18. _In_opt_ HINSTANCE hPrevInstance,
    19. _In_ LPTSTR lpCmdLine,
    20. _In_ int nCmdShow)
    21. {
    22. UNREFERENCED_PARAMETER(hPrevInstance);
    23. UNREFERENCED_PARAMETER(lpCmdLine);
    24. // TODO: 在此放置代码。
    25. MSG msg;
    26. HACCEL hAccelTable;
    27. // 初始化全局字符串
    28. LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    29. LoadString(hInstance, IDC_SDK_3, szWindowClass, MAX_LOADSTRING);
    30. MyRegisterClass(hInstance);
    31. // 执行应用程序初始化:
    32. if (!InitInstance (hInstance, nCmdShow))
    33. {
    34. return FALSE;
    35. }
    36. hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_SDK_3));
    37. // 主消息循环:
    38. while (GetMessage(&msg, NULL, 0, 0))
    39. {
    40. if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
    41. {
    42. TranslateMessage(&msg);
    43. DispatchMessage(&msg);
    44. }
    45. }
    46. return (int) msg.wParam;
    47. }
    48. //
    49. // 函数: MyRegisterClass()
    50. //
    51. // 目的: 注册窗口类。
    52. //
    53. ATOM MyRegisterClass(HINSTANCE hInstance)
    54. {
    55. WNDCLASSEX wcex;
    56. wcex.cbSize = sizeof(WNDCLASSEX);
    57. wcex.style = CS_HREDRAW | CS_VREDRAW;
    58. wcex.lpfnWndProc = WndProc;
    59. wcex.cbClsExtra = 0;
    60. wcex.cbWndExtra = 0;
    61. wcex.hInstance = hInstance;
    62. wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SDK_3));
    63. wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
    64. wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    65. wcex.lpszMenuName = MAKEINTRESOURCE(IDC_SDK_3);
    66. wcex.lpszClassName = szWindowClass;
    67. wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
    68. return RegisterClassEx(&wcex);
    69. }
    70. //
    71. // 函数: InitInstance(HINSTANCE, int)
    72. //
    73. // 目的: 保存实例句柄并创建主窗口
    74. //
    75. // 注释:
    76. //
    77. // 在此函数中,我们在全局变量中保存实例句柄并
    78. // 创建和显示主程序窗口。
    79. //
    80. BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
    81. {
    82. HWND hWnd;
    83. hInst = hInstance; // 将实例句柄存储在全局变量中
    84. hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
    85. CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
    86. if (!hWnd)
    87. {
    88. return FALSE;
    89. }
    90. ShowWindow(hWnd, nCmdShow);
    91. UpdateWindow(hWnd);
    92. return TRUE;
    93. }
    94. //
    95. // 函数: WndProc(HWND, UINT, WPARAM, LPARAM)
    96. //
    97. // 目的: 处理主窗口的消息。
    98. //
    99. // WM_COMMAND - 处理应用程序菜单
    100. // WM_PAINT - 绘制主窗口
    101. // WM_DESTROY - 发送退出消息并返回
    102. //
    103. //
    104. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    105. {
    106. int wmId, wmEvent;
    107. PAINTSTRUCT ps;
    108. HDC hdc;
    109. switch (message)
    110. {
    111. case WM_CREATE:
    112. Init(hWnd);
    113. break;
    114. case WM_COMMAND:
    115. wmId = LOWORD(wParam);
    116. wmEvent = HIWORD(wParam);
    117. // 分析菜单选择:
    118. switch (wmId)
    119. {
    120. case IDC_START:
    121. ::SetTimer(hWnd,1,100,TimerProc);
    122. break;
    123. case IDM_ABOUT:
    124. DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
    125. break;
    126. case IDM_EXIT:
    127. DestroyWindow(hWnd);
    128. break;
    129. default:
    130. return DefWindowProc(hWnd, message, wParam, lParam);
    131. }
    132. break;
    133. case WM_PAINT:
    134. hdc = BeginPaint(hWnd, &ps);
    135. // TODO: 在此添加任意绘图代码...
    136. Draw(hdc);
    137. EndPaint(hWnd, &ps);
    138. break;
    139. case WM_DESTROY:
    140. PostQuitMessage(0);
    141. break;
    142. default:
    143. return DefWindowProc(hWnd, message, wParam, lParam);
    144. }
    145. return 0;
    146. }
    147. // “关于”框的消息处理程序。
    148. INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    149. {
    150. UNREFERENCED_PARAMETER(lParam);
    151. switch (message)
    152. {
    153. case WM_INITDIALOG:
    154. return (INT_PTR)TRUE;
    155. case WM_COMMAND:
    156. if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
    157. {
    158. EndDialog(hDlg, LOWORD(wParam));
    159. return (INT_PTR)TRUE;
    160. }
    161. break;
    162. }
    163. return (INT_PTR)FALSE;
    164. }

    球的动画效果实现了。

  • 相关阅读:
    Python数据分析实战① Python实现数据可视化
    高新技术企业认定工作指导
    阶乘分解(筛素数+分解质因数C++)
    某宝长x-mini-wua分析与破解
    字节跳动二面(消息队列+分布式+CAS+ThreadLocal)
    基于Hardhat和Openzeppelin开发可升级合约(二)
    2004-2019年分省农产品进出口额
    S2B2C供应链系统将引领商业模式!S2B2C供应链电商系统实现订单管理数智化
    [项目管理-5]:软硬件项目管理 - 项目人力资源管理 (人)
    Spring的创建和使用
  • 原文地址:https://blog.csdn.net/yixiaobo2001/article/details/127849425