⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pushbox.cpp

📁 推箱子游戏 为研究A*寻路算法的实现
💻 CPP
字号:
// PushBox.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "resource.h"
#include "DateBase.h"
#include "MyDraw.h"
#include "Astar.h"
#include <mmsystem.h>


// Global Variables:
HINSTANCE hInst;
HWND hWnd;
//自定义控制参数								
int map[9][8] = {0};                //定义全局地图信息
POINT babypoint = {2,4};            //定义全局人物坐标
int babyn=3;                        //记录人物状态
POINT flagpt[10];                   //定义全局旗帜点
int flagn;                          //定义全局旗帜数量
POINT boxpoint[10];                 //定义箱子数组
int boxn=0;                         //定义箱子个数
int box=0;                          //记录箱子状态
int level = 1;                      //定义全局游戏关数
POINT mousepoint;                   //用于暂存鼠标按下坐标

CMyDraw mydraw;                     //定义全局绘图对像
CDateBase getdate;                  //定义全局数据对像
DWORD tPre,tNow;                    //游戏循环时间控制参数
BOOL Lkeydown=FALSE;                //按键确认控制参数
BOOL GameOver;                      //游戏结束参数
             


// Foward declarations of functions included in this code module:
ATOM				MyRegisterClass(HINSTANCE hInstance);
BOOL				InitInstance(HINSTANCE, int);
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK    About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK    SelectPass(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);

//自定义函数
void InitGame(int level);           //游戏初始化
BOOL ProLG();                       //游戏逻辑
void FlagShow();                    //显示旗帜
BOOL IfPass();                      //判断是否过关

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
	MSG msg;

	MyRegisterClass(hInstance);

	if (!InitInstance (hInstance, nCmdShow)) 
	{
		return FALSE;
	}

	// 游戏循环
	while (msg.message!=WM_QUIT) 
	{
		if( PeekMessage( &msg, NULL, 0,0 ,PM_REMOVE) )
        {
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else
		{
			tNow = GetTickCount();
			if(tNow-tPre >= 40 && Lkeydown)
			{
			    ProLG();
				if(GameOver)
				{
					MessageBox(hWnd,"恭喜过关,请进入下一关","congratulation",0);
					level+=1;
					if(level>20)
					{
						MessageBox(hWnd,"居然全部通关!对你的景仰如淘淘江水!","作者致辞",0);
						return msg.wParam;
					}
					else
					{
						GameOver=FALSE;
						Lkeydown=FALSE;
						InitGame(level);
					}
				}
			}
		}
	}

	return msg.wParam;
}

//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX); 

	wcex.style			= CS_VREDRAW | CS_HREDRAW | CS_OWNDC | CS_DBLCLKS;
	wcex.lpfnWndProc	= (WNDPROC)WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= NULL;
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH) GetStockObject (DKGRAY_BRUSH);
	wcex.lpszMenuName	= NULL;
	wcex.lpszClassName	= "poshbox";
	wcex.hIconSm		= LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);

	return RegisterClassEx(&wcex);
}


BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{

   hInst = hInstance;

   HMENU hMenu = LoadMenu (hInstance, MAKEINTRESOURCE (IDR_MENU1)); 

   hWnd = CreateWindowEx(NULL,"poshbox", "推箱子", WS_SYSMENU|WS_MINIMIZEBOX,
      CW_USEDEFAULT, CW_USEDEFAULT, 327,323, NULL, hMenu, hInstance, NULL);

   if (!hWnd)
   {
      return FALSE;
   }

   InitGame(level);

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	PAINTSTRUCT ps;
	HDC hdc;
	int i;

	switch (message) 
	{
	case   WM_COMMAND:
		switch (LOWORD (wParam))        
		{  
		case IDR_EXIT:
			PostQuitMessage(0);
			break;
		case IDR_START:
			InitGame(level);
			break;
		case IDR_SLECTPASS:
			DialogBox(hInst,(LPCTSTR)IDD_DIALOG1,hWnd,(DLGPROC)SelectPass);
			break;
		case IDD_ABOUTBOX:
			DialogBox(hInst,(LPCTSTR)IDD_ABOUTBOX,hWnd,(DLGPROC)About);
			break;
		}
		break;
		
		case WM_PAINT:
			hdc = BeginPaint(hWnd, &ps);
			
			mydraw.DrawJM(map);    //按所传递的地图信息绘制界面
			if(babyn == 1)
				mydraw.DrawBabyR(babypoint);  //绘制人物左
			else if(babyn==2)
				mydraw.DrawBabyL(babypoint);  //绘制人物右
			else if(babyn==3)
				mydraw.DrawBaby(babypoint);   //绘制人物上
			else
				mydraw.DrawBabyB(babypoint);   //绘制人物下
			
			//按箱子所在位置绘制各个箱子
			for(i=0;i<boxn;i++)
			{
				for(int k=0;k<flagn;k++)
				{
					if((boxpoint[i].x ==flagpt[k].x) && (boxpoint[i].y ==flagpt[k].y))
					{
						box = 1;
						k = flagn;
					}
					else
						box = 0;
				}
				if(box == 0)
					mydraw.DrawBox(boxpoint[i]);
				else
					mydraw.DrawBoxn(boxpoint[i]);
			}
			//绘制旗帜
			FlagShow();
			
			EndPaint(hWnd, &ps);
			break;
		case WM_LBUTTONDOWN: 
			mousepoint.x = LOWORD(lParam)/40;
            mousepoint.y = HIWORD(lParam)/30;
			Lkeydown = TRUE;
			break;
		case WM_DESTROY:
			PostQuitMessage(0);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
	}
   return 0;
}

//游戏初始化
void InitGame(int level)
{
	babyn=3;                            //记录人物状态
	boxn = 0;                           //初始化箱子
	
	if(!getdate.InitDate(map,flagpt,flagn,babypoint,level))
		MessageBox(hWnd,"获取地图资料失败","消息",0);

	mousepoint = babypoint;
	
	mydraw.InitMyDraw(hInst,hWnd);  //初始化绘图对像
	
	
    mydraw.DrawJM(map);    //按所传递的地图信息绘制界面
    mydraw.DrawBaby(babypoint);  //绘制人物	

	//初始化箱子
	for(int i=0;i<8;i++)
	{
		for(int j=0;j<9;j++)
		{
			if(map[j][i] == 3)
			{
				boxpoint[boxn].x=i;
				boxpoint[boxn].y=j;
				boxn+=1;
			}
		}
	}
	//按箱子所在位置绘制各个箱子
    for(i=0;i<boxn;i++)
	{
		//检测箱子是否在旗子上
		for(int k=0;k<flagn;k++)
		{
			if((boxpoint[i].x ==flagpt[k].x) && (boxpoint[i].y ==flagpt[k].y))
			{
				box = 1;
				k = flagn;
			}
			else
				box = 0;
		}
		if(box == 0)
			mydraw.DrawBox(boxpoint[i]);
		else
			mydraw.DrawBoxn(boxpoint[i]);
	}
	//绘制旗帜
	FlagShow();
}

BOOL ProLG()             //游戏运行逻辑
{
    //当鼠标点不在人物身上时,人物在空地上移动
    if((!map[mousepoint.y][mousepoint.x])
		&& ((mousepoint.x!=babypoint.x)
		|| (mousepoint.y!=babypoint.y)))
	{
		//A*算法
		int stepn;                                 //步数
		POINT backpoint[56];                       //路径数组
		CAstar a(babypoint,mousepoint);            //构造一个A*算法
		stepn = a.GetWay(map,backpoint);           //返回A*算法路径及步数
		if(stepn == 0)
			MessageBeep(MB_OK);
        //沿路径行走
		for(int i=0;i<stepn;i++)
		{
			babypoint = mydraw.BabyMove(backpoint[i],backpoint[i+1],babyn);
			FlagShow();	
			Sleep(200);
		}		

		tPre = GetTickCount();
		Lkeydown = FALSE;
		return TRUE;		
	}

	//从上、下、左、右四个方向推箱子
	if(map[mousepoint.y][mousepoint.x] == 3)
	{
		for(int i=0;i<boxn;i++)
		{
			if(mousepoint.x-boxpoint[i].x == 0 && mousepoint.y-boxpoint[i].y == 0)
			{
				if((boxpoint[i].x-babypoint.x == -1) 
					&& (boxpoint[i].y-babypoint.y == 0)
					&& !map[boxpoint[i].y][boxpoint[i].x-1]) //左方
				{
					//调整地图数据
					map[boxpoint[i].y][boxpoint[i].x] = 0;
					map[boxpoint[i].y][boxpoint[i].x-1] = 3;
					mydraw.DrawBg(boxpoint[i]);
					boxpoint[i].x = boxpoint[i].x-1;
					//检测箱子是否在旗子上
					for(int k=0;k<flagn;k++)
					{
						if((boxpoint[i].x ==flagpt[k].x) && (boxpoint[i].y ==flagpt[k].y))
						{
							box = 1;
						    k = flagn;
						}
						else
							box = 0;
					}
					if(box == 0)
						mydraw.DrawBox(boxpoint[i]);
					else
						mydraw.DrawBoxn(boxpoint[i]);

					babypoint = mydraw.BabyMove(babypoint,mousepoint,babyn);	
					FlagShow();
					tPre = GetTickCount();
					Lkeydown = FALSE;
                    if(IfPass())
					{
						GameOver = TRUE;						
					}
					return TRUE;
				}
				if((boxpoint[i].x-babypoint.x == 1) 
					&& (boxpoint[i].y-babypoint.y == 0)
					&& !map[boxpoint[i].y][boxpoint[i].x+1]) //右方
				{
					//调整地图数据
					map[boxpoint[i].y][boxpoint[i].x] = 0;
					map[boxpoint[i].y][boxpoint[i].x+1] = 3;
					mydraw.DrawBg(boxpoint[i]);
					boxpoint[i].x = boxpoint[i].x+1;
					//检测箱子是否在旗子上
					for(int k=0;k<flagn;k++)
					{
						if((boxpoint[i].x ==flagpt[k].x) && (boxpoint[i].y ==flagpt[k].y))
						{
							box = 1;
						    k = flagn;
						}
						else
							box = 0;
					}
					if(box == 0)
						mydraw.DrawBox(boxpoint[i]);
					else
						mydraw.DrawBoxn(boxpoint[i]);

					babypoint = mydraw.BabyMove(babypoint,mousepoint,babyn);	
					FlagShow();
					tPre = GetTickCount();
					Lkeydown = FALSE;
                    if(IfPass())
					{
						GameOver = TRUE;						
					}
					return TRUE;
				}
				if((boxpoint[i].y-babypoint.y == -1) 
					&& (boxpoint[i].x-babypoint.x == 0)
					&& !map[boxpoint[i].y-1][boxpoint[i].x]) //上方
				{
					//调整地图数据
					map[boxpoint[i].y][boxpoint[i].x] = 0;
					map[boxpoint[i].y-1][boxpoint[i].x] = 3;
					mydraw.DrawBg(boxpoint[i]);
					boxpoint[i].y = boxpoint[i].y-1;
					//检测箱子是否在旗子上
					for(int k=0;k<flagn;k++)
					{
						if((boxpoint[i].x ==flagpt[k].x) && (boxpoint[i].y ==flagpt[k].y))
						{
							box = 1;
						    k = flagn;
						}
						else
							box = 0;
					}
					if(box == 0)
						mydraw.DrawBox(boxpoint[i]);
					else
						mydraw.DrawBoxn(boxpoint[i]);

					babypoint = mydraw.BabyMove(babypoint,mousepoint,babyn);	
					FlagShow();
					tPre = GetTickCount();
					Lkeydown = FALSE;
                    if(IfPass())
					{
						GameOver = TRUE;						
					}
					return TRUE;
				}
				if((boxpoint[i].y-babypoint.y == 1) 
					&& (boxpoint[i].x-babypoint.x == 0)
					&& !map[boxpoint[i].y+1][boxpoint[i].x]) //下方
				{
					//调整地图数据
					map[boxpoint[i].y][boxpoint[i].x] = 0;
					map[boxpoint[i].y+1][boxpoint[i].x] = 3;
					mydraw.DrawBg(boxpoint[i]);
					boxpoint[i].y = boxpoint[i].y+1;
					//检测箱子是否在旗子上
					for(int k=0;k<flagn;k++)
					{
						if((boxpoint[i].x ==flagpt[k].x) && (boxpoint[i].y ==flagpt[k].y))
						{
							box = 1;
						    k = flagn;
						}
						else
							box = 0;
					}
					if(box == 0)
						mydraw.DrawBox(boxpoint[i]);
					else
						mydraw.DrawBoxn(boxpoint[i]);

					babypoint = mydraw.BabyMove(babypoint,mousepoint,babyn);	
					FlagShow();
					tPre = GetTickCount();
					Lkeydown = FALSE;
                    if(IfPass())
					{
						GameOver = TRUE;						
					}
					return TRUE;
				}
			}
		}
	}

	tPre = GetTickCount();
	Lkeydown = FALSE;
	return FALSE;
}

//显示旗帜,当旗帜上面没有盒子和小孩时
void FlagShow()
{
	for(int i=0;i<flagn;i++)
	{
		if(map[flagpt[i].y][flagpt[i].x]!=3)
		{
			if(!((flagpt[i].x==babypoint.x) && (flagpt[i].y == babypoint.y)))
				mydraw.DrawFlag(flagpt[i]);
		}
	}
		
}
//过关识别
BOOL IfPass()
{
	int k=0;
	for(int i=0;i<flagn;i++)
	{
		for(int j=0;j<boxn;j++)
		{
		if(((flagpt[i].x==boxpoint[j].x) && (flagpt[i].y == boxpoint[j].y)))
			k+=1;
		}
	}
	if(k==flagn)
	{		
		return TRUE;
	}
	return FALSE;
}

LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
	case WM_INITDIALOG:
		return TRUE;
		
	case WM_COMMAND:
		switch(LOWORD(wParam))
		{
		case IDOK:
			EndDialog(hDlg, LOWORD(wParam));
			return TRUE;
			break;	
		case IDCANCEL:
			EndDialog(hDlg, LOWORD(wParam));
			return TRUE;
		}
	}
    return FALSE;
}
//选关
LRESULT CALLBACK SelectPass(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	int lev;
	switch (message)
	{
	case WM_INITDIALOG:
		return TRUE;		
	case WM_COMMAND:
		switch(LOWORD(wParam))
		{
		case IDOK:
			lev = GetDlgItemInt(hDlg,IDC_EDIT1,NULL,FALSE);
			if(lev>0 && lev<=20 && lev!=level)
			{
				level = lev;
				Lkeydown=FALSE;
				InitGame(level);
			}
			else
				MessageBox(hWnd,"仅有20关!","出错了!",0);
			EndDialog(hDlg, LOWORD(wParam));
			return TRUE;
			break;
		case IDCANCEL:
			EndDialog(hDlg, LOWORD(wParam));
			return TRUE;
			break;
		case IDC_EDIT1:			
			return TRUE;
			break;			
		}
	}
    return FALSE;
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -