[游戏模版17] Win32 推箱子 迷宫
>_<:Here introduce a simple game:
>_<:resource
>_<:only can push a box and finally arrive the gate.
1 #include <windows.h> 2 // C 运行时头文件 3 #include <stdlib.h> 4 #include <cstdio> 5 #include <malloc.h> 6 #include <memory.h> 7 #include <tchar.h> 8 #include <time.h> 9 #include <string> 10 #include <stack> 11 12 HINSTANCE hInst; 13 14 HBITMAP ball,tile,dis; 15 HDC hdc,mdc,bufdc; 16 HWND hWnd; 17 DWORD tPre,tNow; 18 int nowPos,prePos;//在上次贴图位置贴白色去除残留影响 19 bool FIND; 20 int rows=5,cols=5; 21 int kind[]={5,8,8,10,10,10,16,16,16,16,20,20,20,20,25,25,25,25,25},KindNum=0; 22 int bilv=400/rows; 23 int Dis;//终点位置 24 int mapIndex[160000]={0,2,0,0,0,0,0,0, 25 0,1,0,1,1,1,1,0, 26 0,1,0,1,0,1,1,0, 27 0,1,0,0,0,1,1,0, 28 0,1,1,1,1,1,1,0, 29 0,1,0,0,0,0,1,0, 30 0,0,1,1,1,1,1,0, 31 0,0,0,0,0,0,3,0}; 32 33 int record[160000];//用来标记不可走方格或已经走过的方格 34 // 此代码模块中包含的函数的前向声明: 35 ATOM MyRegisterClass(HINSTANCE hInstance); 36 BOOL InitInstance(HINSTANCE, int); 37 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 38 INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); 39 void MyPaint(HDC hdc); 40 void CreateMiGong(int Hang); 41 void PreparePaint();//准备阶段绘图 42 43 int APIENTRY _tWinMain(HINSTANCE hInstance, 44 HINSTANCE hPrevInstance, 45 LPTSTR lpCmdLine, 46 int nCmdShow){ 47 48 MSG msg; 49 MyRegisterClass(hInstance); 50 // 执行应用程序初始化: 51 if (!InitInstance (hInstance, nCmdShow)){ 52 return FALSE; 53 } 54 // 主消息循环: 55 while (GetMessage(&msg, NULL, 0, 0)){ 56 TranslateMessage(&msg); 57 DispatchMessage(&msg); 58 } 59 return (int) msg.wParam; 60 } 61 62 // 函数: MyRegisterClass() 63 // 64 // 目的: 注册窗口类。 65 ATOM MyRegisterClass(HINSTANCE hInstance){ 66 WNDCLASSEX wcex; 67 68 wcex.cbSize = sizeof(WNDCLASSEX); 69 70 wcex.style = CS_HREDRAW | CS_VREDRAW; 71 wcex.lpfnWndProc = WndProc; 72 wcex.cbClsExtra = 0; 73 wcex.cbWndExtra = 0; 74 wcex.hInstance = hInstance; 75 wcex.hIcon = NULL; 76 wcex.hCursor = LoadCursor(NULL, IDC_ARROW); 77 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); 78 wcex.lpszMenuName = "Beautifulzzzz"; 79 wcex.lpszClassName = "Beautifulzzzz"; 80 wcex.hIconSm = NULL; 81 82 return RegisterClassEx(&wcex); 83 } 84 85 // 函数: InitInstance(HINSTANCE, int) 86 // 87 // 目的: 保存实例句柄并创建主窗口 88 // 89 // 注释: 90 // 91 // 在此函数中,我们在全局变量中保存实例句柄并 92 // 创建和显示主程序窗口。 93 // 1.设定飞机的初始位置 94 // 2.设定鼠标位置及隐藏 95 // 3.设定鼠标光标移动区域 96 // 97 BOOL InitInstance(HINSTANCE hInstance, int nCmdShow){ 98 99 HBITMAP bmp; 100 101 hInst = hInstance; // 将实例句柄存储在全局变量中 102 103 hWnd = CreateWindow("Beautifulzzzz","Beautifulzzzz", WS_OVERLAPPEDWINDOW, 104 CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); 105 106 if (!hWnd) 107 { 108 return FALSE; 109 } 110 111 MoveWindow(hWnd,10,10,640,480,true); 112 ShowWindow(hWnd, nCmdShow); 113 UpdateWindow(hWnd); 114 115 hdc=GetDC(hWnd); 116 mdc=CreateCompatibleDC(hdc); 117 bufdc=CreateCompatibleDC(hdc); 118 119 bmp=CreateCompatibleBitmap(hdc,cols*bilv,rows*bilv); 120 SelectObject(mdc,bmp); 121 122 PreparePaint(); 123 124 SetTimer(hWnd,1,220,NULL); 125 MyPaint(hdc); 126 127 return TRUE; 128 } 129 130 // 131 // 函数: WndProc(HWND, UINT, WPARAM, LPARAM) 132 // 133 // 目的: 处理主窗口的消息。 134 // 135 // WM_COMMAND - 处理应用程序菜单 136 // WM_PAINT - 绘制主窗口 137 // WM_DESTROY - 发送退出消息并返回 138 // 139 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){ 140 int wmId, wmEvent; 141 int rowNum,colNum; 142 int x,y,up,down,left,right; 143 PAINTSTRUCT ps; 144 145 switch (message) 146 { 147 case WM_KEYDOWN: 148 rowNum=nowPos/cols; 149 colNum=nowPos%rows; 150 x=colNum*bilv; 151 y=rowNum*bilv; 152 153 up=nowPos-cols; 154 down=nowPos+cols; 155 left=nowPos-1; 156 right=nowPos+1; 157 158 switch(wParam){//上下左右 159 case VK_UP: 160 if(up>=0 && mapIndex[up])//往上走 161 { 162 prePos=nowPos; 163 nowPos=up; 164 165 if(mapIndex[nowPos]==3) 166 FIND=true; 167 168 MyPaint(hdc); 169 } 170 else if(up>=cols && !mapIndex[up] && mapIndex[up-cols]==1)//向上推箱子 171 { 172 mapIndex[up]=1; 173 mapIndex[up-cols]=0; 174 SelectObject(bufdc,tile); 175 BitBlt(mdc,bilv*((up-cols)%rows),bilv*((up-cols)/cols),bilv,bilv,bufdc,0,0,SRCCOPY); 176 177 prePos=nowPos; 178 nowPos=up; 179 180 MyPaint(hdc); 181 }break; 182 case VK_DOWN: 183 if(down<=cols*rows-1 && mapIndex[down])//往下走 184 { 185 prePos=nowPos; 186 nowPos=down; 187 188 if(mapIndex[nowPos]==3) 189 FIND=true; 190 191 MyPaint(hdc); 192 } 193 else if(down<=cols*rows-cols-1 && !mapIndex[down] && mapIndex[down+cols]==1)//向下推箱子 194 { 195 mapIndex[down]=1; 196 mapIndex[down+cols]=0; 197 SelectObject(bufdc,tile); 198 BitBlt(mdc,bilv*((down+cols)%rows),bilv*((down+cols)/cols),bilv,bilv,bufdc,0,0,SRCCOPY); 199 200 prePos=nowPos; 201 nowPos=down; 202 203 MyPaint(hdc); 204 }break; 205 case VK_LEFT: 206 if(left>=rowNum*cols && mapIndex[left])//往左走 207 { 208 prePos=nowPos; 209 nowPos=left; 210 211 if(mapIndex[nowPos]==3) 212 FIND=true; 213 214 MyPaint(hdc); 215 } 216 else if(left>=rowNum*cols+1 && !mapIndex[left] && mapIndex[left-1]==1)//往左推箱子 217 { 218 mapIndex[left]=1; 219 mapIndex[left-1]=0; 220 SelectObject(bufdc,tile); 221 BitBlt(mdc,bilv*((left-1)%rows),bilv*((left-1)/cols),bilv,bilv,bufdc,0,0,SRCCOPY); 222 223 prePos=nowPos; 224 nowPos=left; 225 226 MyPaint(hdc); 227 }break; 228 case VK_RIGHT: 229 if(right<=(rowNum+1)*cols-1 && mapIndex[right])//往右走 230 { 231 prePos=nowPos; 232 nowPos=right; 233 234 if(mapIndex[nowPos]==3) 235 FIND=true; 236 237 MyPaint(hdc); 238 } 239 else if(right<=(rowNum+1)*cols-2 && !mapIndex[right] && mapIndex[right+1]==1)//往右推箱子 240 { 241 mapIndex[right]=1; 242 mapIndex[right+1]=0; 243 SelectObject(bufdc,tile); 244 BitBlt(mdc,bilv*((right+1)%rows),bilv*((right+1)/cols),bilv,bilv,bufdc,0,0,SRCCOPY); 245 246 prePos=nowPos; 247 nowPos=right; 248 249 MyPaint(hdc); 250 }break; 251 } 252 break; 253 case WM_TIMER: 254 A:MyPaint(hdc); 255 break; 256 case WM_PAINT: 257 hdc = BeginPaint(hWnd, &ps); 258 goto A;// TODO: 在此添加任意绘图代码... 259 EndPaint(hWnd, &ps); 260 break; 261 case WM_DESTROY: 262 DeleteDC(mdc); 263 DeleteDC(bufdc); 264 DeleteObject(ball); 265 DeleteObject(tile); 266 267 KillTimer(hWnd,1); 268 ReleaseDC(hWnd,hdc); 269 PostQuitMessage(0); 270 break; 271 default: 272 return DefWindowProc(hWnd, message, wParam, lParam); 273 } 274 return 0; 275 } 276 277 void MyPaint(HDC hdc){ 278 char* str; 279 int rowNum,colNum; 280 int x,y; 281 int up,down,left,right; 282 283 //清除上次贴图 284 rowNum=prePos/cols; 285 colNum=prePos%rows; 286 x=colNum*bilv; 287 y=rowNum*bilv; 288 SelectObject(bufdc,ball); 289 BitBlt(mdc,x,y,bilv,bilv,bufdc,0,0,WHITENESS); 290 291 //小球贴图 292 rowNum=nowPos/cols; 293 colNum=nowPos%rows; 294 x=colNum*bilv; 295 y=rowNum*bilv; 296 SelectObject(bufdc,ball); 297 BitBlt(mdc,x,y,bilv,bilv,bufdc,0,0,SRCCOPY); 298 299 if(!FIND){ 300 str = "找寻出口中..."; 301 }else{ 302 str="找到出口了!"; 303 cols=rows=kind[(++KindNum)%19]; 304 PreparePaint(); 305 } 306 307 rowNum=Dis/cols; 308 colNum=Dis%rows; 309 x=colNum*bilv; 310 y=rowNum*bilv; 311 SelectObject(bufdc,dis); 312 BitBlt(mdc,x,y,bilv,bilv,bufdc,0,0,SRCCOPY); 313 314 TextOutA(hdc,430,10,str,strlen(str)); 315 BitBlt(hdc,10,10,cols*bilv,rows*bilv,mdc,0,0,SRCCOPY); 316 } 317 /*生成迷宫函数*/ 318 void CreateMiGong(int Hang){ 319 srand((unsigned)time(NULL)); 320 for(int i=0;i<Hang*Hang;i++) 321 mapIndex[i]=rand()%2; 322 mapIndex[rand()%(Hang*Hang)]=2; 323 mapIndex[Dis=rand()%(Hang*Hang)]=3; 324 } 325 /*准备阶段贴图*/ 326 void PreparePaint(){ 327 bilv=400/rows; 328 tile=(HBITMAP)LoadImageA(NULL,"tile.bmp",IMAGE_BITMAP,bilv,bilv,LR_LOADFROMFILE); 329 ball=(HBITMAP)LoadImageA(NULL,"ball.bmp",IMAGE_BITMAP,bilv,bilv,LR_LOADFROMFILE); 330 dis=(HBITMAP)LoadImageA(NULL,"dis.bmp",IMAGE_BITMAP,bilv,bilv,LR_LOADFROMFILE); 331 332 int rowNum,colNum,x,y; 333 CreateMiGong(cols); 334 //按照mapIndex数组中的定义进行迷宫拼接 335 //贴上终点 336 for(int i=0;i<rows*cols;i++){ 337 record[i]=mapIndex[i]; 338 339 rowNum=i/cols;//列编号 340 colNum=i%rows;//行编号 341 x=colNum*bilv;//求贴图x坐标 342 y=rowNum*bilv;//求贴图y坐标 343 344 SelectObject(bufdc,tile); 345 346 if(!mapIndex[i])//墙 347 BitBlt(mdc,x,y,bilv,bilv,bufdc,0,0,SRCCOPY); 348 else { 349 if(mapIndex[i]==2){//迷宫入口 350 nowPos=i; 351 mapIndex[i]=1; 352 } 353 BitBlt(mdc,x,y,bilv,bilv,bufdc,0,0,WHITENESS); 354 } 355 } 356 prePos=cols*rows+1;//第一次在窗口外绘图不影响效果,以后记录上一次小球位置并贴图覆盖原来小球影像 357 FIND=false; 358 }