<Win32_3>Bitmap位图应用2 ------ 键盘控制人物走动
  YSzrYKYMzpiK 2023年11月02日 62 0


今天掌握了Bitmap的用法,忍不住再来一次升级版的应用------用键盘控制人物的走动,这个可能在游戏设计中用的很多,不过今儿就先来小试牛刀,呵呵……

 

本人学习编程有个"癖好"  —— 那就是有了想法,下一步就是实现,越快实现越好,不实现就誓不罢休……

 

好了,F话少说了,还是先来逐步了解需求吧

(1)首先需要一个完整的人物走路分解图,每一个方向4张,分别是:直立、右脚向前、直立、左脚向前

(资源由本人亲自制作,待会儿上传^_^)

(2)加载位图到内存中,这个和Bitmap应用1一样,不再赘述

(3)获取位图ID

首先需要写两个方法:


[cpp]  
1. IDB_BITMAP GetBitmapID(int dir, int dirCount);                  //获取当前绘制的位图ID  
2. void DrawBitmap(HINSTANCE, HDC, int, int, int, int);    //绘制位图  
3. (IDB_BITMAP就是int)

 

本程序总共需要16张位图,位图ID是从101开始,每一张是紧挨着的(101~116),所以可以通过ID这个特点来控制位图的选择

GetBitmapID()的参数dir取以下4个之1:(位图的排列顺序为: 前后左右)


[cpp]  
1. //位图的方位  
2. #define DIR_FRONT   0  
3. #define DIR_REAR    1  
4. #define DIR_LEFT    2  
5. #define DIR_RIGHT   3


参数dirCount取以下4个之1(也就是方向键连续按下的次数,每次对4求余数,因为每一个方向有4张分解图)


[cpp]  
1. static int      frontC, rearC, leftC, rightC;  
2. //计数是为了控制每个方向所显示状态(立正、右脚向前、立正、左脚向前)


然后简单的运算就能得到相应的位图ID号:

101 + dir*4 + dirCount

 

(4)用键盘控制人物的走动

由于每一个方向的处理类似,这里就简述一下向前走的控制算法:


[cpp]  
1. rearC=leftC=rightC=0;//清除  
2.   
3. //控制移动的距离  
4. if(!(frontC % 2))   //当人物直立时,移动距离控制为10  
5. {  
6.     y += 10;  
7. }         
8. else        //当人物左脚或右脚向前时,移动距离控制为2   这是经过多次测试得到的数据,这样控制的效果较好  
9. {  
10.     y += 2;  
11. }  
12.   
13. DrawBitmap(hInstance, hdc, DIR_FRONT, frontC, x, y);//绘制人物的状态  
14. frontC = (frontC+1) % 4;//计算本方向(如果继续按下Dowm键)的下一次移动


 

(5)清除上一步的状态,也就是将上一步的位图刷掉

方法还是调用BitBlt()方法,只不过是绘制一块白色的位图,仅仅需要将最后一个参数设定为WHITENESS就ok了

 

好了这就是全过程,以下就是完整代码:


[cpp]   
1. //前后左右移动的小猫  
2. #include<windows.h>  
3. #include<stdio.h>  
4. #include"resource.h"  
5.   
6. //位图的方位  
7. #define DIR_FRONT   0  
8. #define DIR_REAR    1  
9. #define DIR_LEFT    2  
10. #define DIR_RIGHT   3  
11.   
12. //类型的重定义  
13. typedef int         IDB_BITMAP;  
14.   
15. /**    为重绘保存上一步的信息    **/  
16. //保存上一步的位图  
17. BITMAP  lastBitmap;  
18. //保存上一步位图的坐标  
19. int     lastX, lastY;  
20. //保存上一步位图的方向和按键计数  
21. int     lastDir, lastDirCount;  
22.   
23. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);  
24. IDB_BITMAP GetBitmapID(int, int);                       //获取当前绘制的位图ID  
25. void DrawBitmap(HINSTANCE, HDC, int, int, int, int);    //绘制位图  
26.   
27. int WINAPI WinMain(HINSTANCE hInstance,  
28. HINSTANCE hPrevInstance,  
29. PSTR szCmdLine,  
30. int iCmdShow)  
31. {  
32. static  TCHAR   szAppName[] = TEXT("MoveCat");  
33. HWND            hwnd;  
34.     MSG             msg;  
35.     WNDCLASS        wndclass;  
36.       
37.     wndclass.style          = CS_HREDRAW | CS_VREDRAW;  
38.     wndclass.lpfnWndProc    = WndProc;  
39.     wndclass.cbClsExtra     = 0;  
40.     wndclass.cbWndExtra     = 0;  
41.     wndclass.hInstance      = hInstance;  
42.     wndclass.hIcon          = LoadIcon(NULL, IDI_APPLICATION);  
43.     wndclass.hCursor        = LoadCursor(NULL, IDC_ARROW);  
44. HBRUSH)GetStockObject(WHITE_BRUSH);  
45.     wndclass.lpszMenuName   = NULL;  
46.     wndclass.lpszClassName  = szAppName;  
47.       
48. if(!RegisterClass(&wndclass))  
49.     {  
50. "This program requires Windows NT!"),  
51.             szAppName, MB_ICONERROR);  
52. return 0;  
53.     }  
54.       
55.     hwnd = CreateWindow(szAppName,  
56. "MoveCat Demo"),  
57.                         WS_OVERLAPPEDWINDOW,  
58.                         (1366 - 720) / 2,  
59.                         (768 - 570) / 2,  
60.                         720,  
61.                         570,  
62.                         NULL,  
63.                         NULL,  
64.                         hInstance,  
65.                         NULL);  
66.   
67.     ShowWindow(hwnd, iCmdShow);  
68.     UpdateWindow(hwnd);  
69.   
70. while(GetMessage(&msg, NULL, 0, 0))  
71.     {  
72.         TranslateMessage(&msg);  
73.         DispatchMessage(&msg);  
74.     }  
75.       
76. return msg.wParam;  
77. }  
78.   
79. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)  
80. {  
81. static HINSTANCE    hInstance;//窗口的实例句柄  
82. static int          frontC, rearC, leftC, rightC, x, y;  
83. //分别表示方位键按键计数和位图显示的位置  计数是为了控制每个方向所显示状态(立正、右脚向前、立正、左脚向前)  
84. HDC                 hdc;  
85.     PAINTSTRUCT         ps;  
86.       
87. switch(message)  
88.     {  
89. case WM_CREATE:  
90.         hInstance = ((LPCREATESTRUCT)lParam)->hInstance;  
91. return 0 ;  
92.   
93. case WM_PAINT:  
94.         hdc = BeginPaint(hwnd, &ps);  
95.   
96. if(lastBitmap.bmWidth)  
97.         {  
98.             DrawBitmap(hInstance, hdc, lastDir, lastDirCount, lastX, lastY);  
99.         }  
100. else  
101.         {  
102.             DrawBitmap(hInstance, hdc, DIR_FRONT, frontC, x, y);  
103.             frontC = (frontC + 1) % 4;  
104.         }  
105.   
106.         EndPaint(hwnd, &ps);  
107. return 0;  
108.   
109. //用键盘控制位图的显示  
110. case WM_KEYDOWN:  
111.         hdc = GetDC(hwnd);  
112.   
113. switch(wParam)  
114.         {  
115. //向前  
116. case VK_UP:  
117. //清空除当前方向的所有计数  
118.               
119. //控制移动的距离  
120. if(!(rearC % 2))  
121.             {  
122.                 y -= 10;  
123.             }  
124. else  
125.             {  
126.                 y -= 2;  
127.             }  
128.   
129.             DrawBitmap(hInstance, hdc, DIR_REAR, rearC, x, y);  
130.             rearC = (rearC+1) % 4;  
131.               
132. break;  
133.   
134. //向后  
135. case VK_DOWN:  
136.             rearC=leftC=rightC=0;  
137.   
138. //控制移动的距离  
139. if(!(frontC % 2))  
140.             {  
141.                 y += 10;  
142.             }  
143. else  
144.             {  
145.                 y += 2;  
146.             }  
147.   
148.             DrawBitmap(hInstance, hdc, DIR_FRONT, frontC, x, y);  
149.             frontC = (frontC+1) % 4;  
150.   
151. break;  
152.   
153. //向左  
154. case VK_LEFT:  
155.             frontC=rearC=rightC=0;  
156.   
157. //控制移动的距离  
158. if(!(leftC % 2))  
159.             {  
160.                 x -= 15;  
161.             }  
162. else  
163.             {  
164.                 x -= 3;  
165.             }  
166.   
167.             DrawBitmap(hInstance, hdc, DIR_LEFT, leftC, x, y);            
168.             leftC = (leftC+1) % 4;  
169.               
170. break;  
171.   
172. //向右  
173. case VK_RIGHT:  
174.             frontC=rearC=leftC=0;  
175.   
176. //控制移动的距离  
177. if(!(rightC % 2))  
178.             {  
179.                 x += 15;  
180.             }  
181. else  
182.             {  
183.                 x += 3;  
184.             }  
185.   
186.             DrawBitmap(hInstance, hdc, DIR_RIGHT, rightC, x, y);  
187.             rightC = (rightC+1) % 4;  
188.   
189. break;  
190.         }  
191.         ReleaseDC(hwnd, hdc);  
192. return 0;  
193.   
194. case WM_DESTROY:  
195.         PostQuitMessage(0);  
196. return 0;  
197.     }  
198.   
199. return DefWindowProc(hwnd, message, wParam, lParam);  
200. }  
201.   
202. IDB_BITMAP GetBitmapID(int dir, int dirCount)  
203. {  
204. return 101 + dir*4 + dirCount;  
205. }  
206.   
207. //绘制位图  
208. void DrawBitmap(HINSTANCE hInstance, HDC hdc, int dir, int dirCount, int x, int y)  
209. {  
210. HBITMAP hBitmap;  
211.     BITMAP  bitmap;  
212. HDC     hdcMem;  
213.   
214. //用于创建和hdc兼容的内存设备控制表句柄  也就相当于在内存中绘图,一个缓冲(当然,位图也能支持"截图")  
215.     hdcMem = CreateCompatibleDC(hdc);  
216.   
217.     hBitmap = LoadBitmap(hInstance, MAKEINTRESOURCE(GetBitmapID(dir, dirCount)));  
218. sizeof(BITMAP), &bitmap);  
219.     SelectObject(hdcMem, hBitmap);  
220.   
221. //清除上一步位图信息  
222. if(lastBitmap.bmWidth)  
223.     {  
224.         BitBlt(hdc, lastX - 1, lastY - 1, lastBitmap.bmWidth + 1, lastBitmap.bmHeight + 1, hdcMem, 0, 0, WHITENESS);  
225.     }  
226.   
227. //保存上一步信息  
228.     lastX = x;  
229.     lastY = y;  
230.     lastDir = dir;  
231.     lastDirCount = dirCount;  
232.     lastBitmap = bitmap;  
233.   
234. //绘制当前位图信息  
235.     BitBlt(hdc, x, y, bitmap.bmWidth - 1, bitmap.bmHeight - 1, hdcMem, 0, 0, SRCCOPY);  
236.   
237.     DeleteObject(hBitmap);  
238.     DeleteDC(hdcMem);  
239. }



 

运行效果:


<Win32_3>Bitmap位图应用2 ------ 键盘控制人物走动_#include

download

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论