自己动手写推箱子游戏——界面(源码)

MFC开发自己的推箱子游戏

源码下载地址:http://download.csdn.net/source/3503308

第一:推箱子游戏的主界面

游戏的主界面其实就是8×8的区域,在初始化函数中定义它们的矩形区域,里面是我自己收集的8个选关

void CPushBoxDlg::Initi_State(int i,int j) { //int i,j; video_flag=0; num_video=-1; text=""; num_step=0; num_DB=0;//初始化箱子和目的地重合个数 for(i=0;i<8;i++) for(j=0;j<8;j++) face[i][j]=-1;//先全部表示成空 switch(num_hard) { case 1:sitex=4;sitey=4;//初始化人的初位置 num_box=4; //初始化墙的位置 for(i=2;i<=4;i++) face[0][i]=0; for(i=1;i<=3;i++) face[i][2]=0; for(i=0;i<=2;i++) face[3][i]=0; face[4][0]=0; for(i=0;i<=3;i++) face[5][i]=0; face[6][3]=0; for(i=3;i<=5;i++) face[7][i]=0; for(i=4;i<=6;i++) face[i][5]=0; face[4][6]=0; for(i=2;i<=4;i++) face[i][7]=0; for(i=4;i<=7;i++) face[2][i]=0; face[1][4]=0; //初始化箱子的位置 face[3][3]=face[3][5]=face[4][3]=face[5][4]=2; //初始化目的地的位置 face[1][3]=face[4][1]=face[6][4]=face[3][6]=4; //初始化人的位置 face[4][4]=3; //初始化通道的位置 face[2][3]=face[4][2]=face[3][4]=1; break; case 2:sitex=6;sitey=3; num_box=4; //初始化墙的位置 for(i=2;i<=5;i++) face[0][i]=0; for(i=1;i<=2;i++) { face[i][2]=0;face[i][5]=0; } for(i=2;i<=4;i++) { face[i][1]=face[i][6]=0; } for(i=4;i<=7;i++) face[i][0]=face[i][7]=0; for(i=0;i<=7;i++) face[7][i]=0; face[5][3]=0; //初始化箱子的位置 face[1][3]=face[1][4]=face[2][4]=face[3][5]=4; //初始化人的位置 face[6][3]=3; //初始化目的地的位置 face[3][4]=face[4][3]=face[5][4]=face[5][5]=2; //初始化通道的位置 for(i=3;i<=6;i++) face[i][2]=1; face[5][1]=face[6][1]=face[4][4]=face[4][5]=1; for(i=4;i<=6;i++) face[6][i]=1; face[2][3]=face[3][3]=1; face[5][6]=1; break; case 3:sitex=3;sitey=1; num_box=5; //初始化墙 for(i=2;i<=7;i++) face[0][i]=0; face[1][2]=0; for(i=0;i<=2;i++) face[2][i]=0; for(i=3;i<=5;i++) face[i][0]=0; for(i=1;i<=3;i++) face[5][i]=0; for(i=3;i<=6;i++) face[6][i]=0; for(i=1;i<=4;i++) face[i][7]=0; face[4][6]=face[5][6]=0; //初始化人 face[3][1]=3;//初始化箱子 face[4][2]=face[3][3]=face[2][3]=face[2][4]=face[2][5]=2; //初始化目的地 face[3][4]=face[3][5]=face[4][3]=face[4][4]=face[4][5]=4; //初始化通道 for(i=3;i<=6;i++) face[1][i]=1; face[2][6]=face[3][6]=face[3][2]=face[5][4]=face[5][5]=face[4][1]=1; break; case 4:sitex=1;sitey=5; num_box=4; //初始化墙 for(i=2;i<=6;i++) face[0][i]=0; for(i=0;i<=2;i++) face[1][i]=0; for(i=2;i<=4;i++) face[i][0]=face[5][6]=face[1][6]=face[2][6]=0; face[4][1]=0; for(i=4;i<=6;i++) face[i][2]=0; for(i=2;i<=6;i++) face[6][i]=0; for(i=2;i<=5;i++) face[i][7]=0; //ren face[1][5]=3; //箱子 face[2][3]=face[3][4]=face[4][5]=2; face[2][4]=face[3][3]=face[3][5]=4; face[4][4]=6; //初始化通道 face[1][3]=face[1][4]=face[2][1]=face[2][2]=face[2][5]=1; face[3][1]=face[3][2]=face[3][6]=face[4][3]=face[4][6]=1; for(i=3;i<=5;i++) face[5][i]=1; break; case 5:sitex=3;sitey=1; num_box=6; //墙 for(i=0;i<=7;i++) { face[0][i]=0; face[6][i]=0; } for(i=0;i<=6;i++) { face[i][0]=0; face[i][7]=0; } face[1][3]=face[3][6]=face[5][3]=0; face[3][1]=3;//人 for(i=2;i<=4;i++) face[i][2]=2; face[2][5]=face[4][5]=2; face[3][4]=6; for(i=2;i<=4;i++) face[i][3]=4; face[2][4]=face[4][4]=4; //通道 for(i=4;i<=6;i++) { face[1][i]=1; face[5][i]=1; } face[1][1]=face[1][2]=face[2][1]=1; face[4][1]=face[5][1]=face[5][2]=1; face[2][6]=face[3][5]=face[4][6]=1; break; case 6:sitex=4;sitey=2; num_box=8; for(i=0;i<=6;i++) face[0][i]=face[7][i]=0; for(i=0;i<=7;i++) face[i][0]=face[i][6]=0; face[2][3]=face[6][3]=0; //人 face[4][2]=3; for(i=2;i<=4;i++) face[3][i]=face[5][i]=2; face[1][3]=face[4][3]=2; //目的地 for(i=1;i<=2;i++) { face[1][i]=face[2][i]=4; face[1][i+3]=face[2][i+3]=4; } for(i=3;i<=6;i++) face[i][1]=face[i][5]=1; face[6][2]=face[6][4]=face[4][4]=1; break; case 7:sitex=5;sitey=3; num_box=6; //墙 for(i=1;i<=6;i++) { face[0][i]=0; } for(i=1;i<=5;i++) face[i][0]=face[i][7]=0; for(i=2;i<=5;i++) face[6][i]=0; face[1][1]=face[1][6]=face[5][1]=face[5][2]=face[5][5]=face[5][6]=0; //人 face[5][3]=3; for(i=1;i<=6;i++) face[3][i]=4; face[2][2]=face[2][4]=face[2][5]=face[4][2]=face[4][3]=face[4][5]=2; for(i=2;i<=5;i++) face[1][i]=1; face[2][1]=face[2][3]=face[2][6]=face[4][1]=face[4][4]=face[4][6]=face[5][4]=1; break; case 8: sitex=6;sitey=2; num_box=5; for(i=1;i<=6;i++) face[0][i]=0; for(i=1;i<=3;i++) face[i][1]=face[i][6]=0; for(i=3;i<=7;i++) face[i][0]=face[i][7]=0; for(i=0;i<=7;i++) face[7][i]=0; face[3][2]=face[5][2]=face[5][4]=face[5][5]=0; face[6][2]=3; face[1][2]=face[2][2]=face[1][4]=face[1][5]=face[2][5]=4; face[2][4]=face[3][5]=face[4][5]=face[4][2]=face[5][3]=2; for(i=1;i<=4;i++) face[i][3]=1; for(i=4;i<=6;i++) face[i][1]=face[i][6]=1; for(i=3;i<=6;i++) face[6][i]=1; face[3][4]=face[4][4]=1; break; default:break; } for(i=0;i<=MAX-1;i++) CPushBoxDlg::face_to_video(&record[i]); }


界面是绘制,将箱子,人,通道,墙等各种状态分别用枚举或数值表示出来

由于枚举赋值比较麻烦,我就用数值表示状态,

-1:空,0:墙;1:通道;2:箱子;3:人;4:目的地;5:人和目的地重合;6:箱子和目的地重合

接下来就是根据状态绘制不同的图形了,

void CPushBoxDlg::draw_box(CRect rect,CDC *dc) { //CClientDC dc(this); pold=dc->SelectObject(&low); dc->Rectangle(rect); pold=dc->SelectObject(&yellow); dc->Rectangle(rect.left,rect.top,rect.right,rect.top+5); dc->Rectangle(rect.left,rect.bottom,rect.right,rect.bottom-5); dc->Rectangle(rect.left,rect.top,rect.left+5,rect.bottom); dc->Rectangle(rect.right-5,rect.top,rect.right,rect.bottom); dc->Rectangle(rect.left+22,rect.top,rect.left+28,rect.bottom); dc->Rectangle(rect.left,rect.top+22,rect.right,rect.top+28); dc->SelectObject(pold); DeleteObject(&low); // delete &low; // delete &yellow; // delete dc; DeleteObject(&yellow); DeleteObject(dc); } void CPushBoxDlg::draw_box_place(CRect rect,CDC *dc) { //只需要将箱子改变颜色,改成红色就可以 pold=dc->SelectObject(&low); dc->Rectangle(rect); pold=dc->SelectObject(&red); dc->Rectangle(rect.left,rect.top,rect.right,rect.top+5); dc->Rectangle(rect.left,rect.bottom,rect.right,rect.bottom-5); dc->Rectangle(rect.left,rect.top,rect.left+5,rect.bottom); dc->Rectangle(rect.right-5,rect.top,rect.right,rect.bottom); dc->Rectangle(rect.left+22,rect.top,rect.left+28,rect.bottom); dc->Rectangle(rect.left,rect.top+22,rect.right,rect.top+28); dc->SelectObject(pold); DeleteObject(&low); DeleteObject(&red); //delete &low; // delete &yellow; // delete dc; DeleteObject(dc); } void CPushBoxDlg::draw_man(CRect rect,CDC *dc) { CPushBoxDlg::draw_path(rect,dc); pold=dc->SelectObject(&red); dc->Ellipse(CRect(rect.left+15,rect.top+5,rect.left+35,rect.top+25));//话头 dc->Rectangle(rect.left+23,rect.top+25,rect.left+27,rect.bottom); dc->Rectangle(rect.left+5,rect.top+33,rect.right-5,rect.top+37); dc->SelectObject(pold); DeleteObject(dc); DeleteObject(&red); //delete &red; //delete &yellow; // delete dc; } void CPushBoxDlg::draw_path(CRect rect,CDC *dc) { pold=dc->SelectObject(&low1); dc->Rectangle(rect); pold=dc->SelectObject(&blue); dc->Rectangle(rect.left,rect.top,rect.left+20,rect.top+20); dc->Rectangle(rect.right-20,rect.top,rect.right,rect.top+20); dc->Rectangle(rect.left,rect.bottom-20,rect.left+20,rect.bottom); dc->Rectangle(rect.right-20,rect.bottom-20,rect.right,rect.bottom); dc->Rectangle(rect.left+20,rect.top+20,rect.left+30,rect.top+30); dc->SelectObject(pold); DeleteObject(dc); DeleteObject(&low1); DeleteObject(&blue); //delete &blue; //delete dc; } void CPushBoxDlg::draw_place(CRect rect,CDC *dc) { CPushBoxDlg::draw_path(rect,dc); CBrush *pold=dc->SelectObject(&low2); dc->Ellipse(rect.left+10,rect.top+10,rect.right-10,rect.bottom-10); pold=dc->SelectObject(&blue1); dc->Ellipse(rect.left+20,rect.top+20,rect.right-20,rect.bottom-20); dc->SelectObject(pold); DeleteObject(&blue1); DeleteObject(&low2); DeleteObject(dc); // delete &blue; //delete dc; } void CPushBoxDlg::draw_wall(CRect rect,CDC *dc) { pold=dc->SelectObject(&low_gray);//先全部绘成浅灰 dc->Rectangle(rect); pold=dc->SelectObject(&gray); dc->Rectangle(rect.left,rect.top,rect.left+20,rect.top+20); dc->Rectangle(rect.left+30,rect.top,rect.left+50,rect.top+20); dc->Rectangle(rect.left,rect.top+30,rect.left+20,rect.top+50); dc->Rectangle(rect.left+30,rect.top+30,rect.left+50,rect.top+50); dc->SelectObject(pold); DeleteObject(&gray); DeleteObject(&low_gray); DeleteObject(dc); }

接下来就是绘制整个界面的函数,就是根据各个区域的状态绘制不同的图形

void CPushBoxDlg::draw_game_face(CDC *dc) { //int i,j; CRect *rect; rect=new CRect; for(ii=0;ii<=7;ii++) for(jj=0;jj<=7;jj++) { rect->left=START+jj*50; rect->right=START+(jj+1)*50; rect->top=START+ii*50; rect->bottom=START+(ii+1)*50; switch(face[ii][jj]) { case 0:CPushBoxDlg::draw_wall(rect,dc);break; case 1:CPushBoxDlg::draw_path(rect,dc);break; case 2:CPushBoxDlg::draw_box(rect,dc);break; case 3:CPushBoxDlg::draw_man(rect,dc);break; case 4:CPushBoxDlg::draw_place(rect,dc);break; case 5:CPushBoxDlg::draw_man(rect,dc);break; case 6:CPushBoxDlg::draw_box_place(rect,dc);break; case -1:break; } } delete rect; }

最后就是控制键盘来移动了,其实原理很简单,就是通过改变不同区域的状态,然后重绘图形就好了。但是这需要在虚函数PreTranslateMessage(MSG* pMsg)中实现,推箱子的算法其实很简单就是多一些switch语句罢了,耐心一点就不会错了

BOOL CPushBoxDlg::PreTranslateMessage(MSG* pMsg) //处理按键消息函数 { if(pMsg->message==WM_KEYDOWN) { switch(pMsg->wParam) { case VK_LEFT: CPushBoxDlg::start_video(); CPushBoxDlg::move_up(); break; case VK_RIGHT: CPushBoxDlg::start_video(); CPushBoxDlg::move_down(); break; case VK_UP: CPushBoxDlg::start_video(); CPushBoxDlg::move_left(); break; case VK_DOWN: CPushBoxDlg::start_video(); CPushBoxDlg::move_right(); break; //case VK_RETURN:MessageBox("kkk"); default:break; } CPushBoxDlg::face_to_video(&record[MAX-1]); //RedrawWindow(); text.Format("你的位置 X: %d Y: %d",sitey,sitex); m_StatusBar.SetPaneText(0,text); text.Format("你走的步骤数: %d",num_step); m_StatusBar.SetPaneText(1,text); //RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0); //CPushBoxDlg::OnPaint(); CPushBoxDlg::check_result(); if(num_DB==num_box) { if(flag==false) MessageBox("Well done!","友情提示"); flag=true; } } return CDialog::PreTranslateMessage(pMsg); }当然为了避免繁琐,我把上下左右移动设成函数了:
void CPushBoxDlg::move_down()
{
	switch(face[sitex][sitey+1])
	{
	case 0:break;//遇到墙
	case 1:if(face[sitex][sitey]==3)
		   {
			   face[sitex][sitey]=1;
			   sitey+=1;
			   face[sitex][sitey]=3;
		   }
		else
			if(face[sitex][sitey]==5)
			{
				face[sitex][sitey]=4;
				sitey+=1;
				face[sitex][sitey]=3;
			}
			CPushBoxDlg::draw_game_face(dc);num_step++;
			break;
	case 2:switch(face[sitex][sitey+2])
		   {
	case 0:break;
	case 1:if(face[sitex][sitey]==3)
		   {
			   face[sitex][sitey]=1;
			   face[sitex][sitey+1]=3;
			   face[sitex][sitey+2]=2;
			   sitey+=1;
		   }
							 else
								 if(face[sitex][sitey]==5)
								 {
									 face[sitex][sitey]=4;
									 face[sitex][sitey+1]=3;
									 face[sitex][sitey+2]=2;
									 sitey+=1;
								 }CPushBoxDlg::draw_game_face(dc);num_step++;break;
	case 2:break;
	case 3:break;
	case 4:if(face[sitex][sitey]==3)//人时
		   {
			   face[sitex][sitey]=1;
			   face[sitex][sitey+1]=3;
			   face[sitex][sitey+2]=6;
			   sitey+=1;
		   }
		else
			if(face[sitex][sitey]==5)
			{
				face[sitex][sitey]=4;
				face[sitex][sitey+1]=3;
				face[sitex][sitey+2]=6;
				sitey+=1;
			}CPushBoxDlg::draw_game_face(dc);num_step++;break;
			
	case 5:break;
	case 6:break;
		   } 
		break;
	case 3:break;
	case 4:if(face[sitex][sitey]==3)//人时
		   {
			   face[sitex][sitey]=1;
			   sitey+=1;
			   face[sitex][sitey]=5;
		   }
		else
			if(face[sitex][sitey]==5)
			{
				face[sitex][sitey]=4;
				sitey+=1;
				face[sitex][sitey]=5;
			}CPushBoxDlg::draw_game_face(dc);num_step++;
			break;
	case 5:break;
	case 6:switch(face[sitex][sitey+2])
		   {
	case 0:break;
	case 1:if(face[sitex][sitey]==3)//人时
		   {
			   face[sitex][sitey]=1;
			   face[sitex][sitey+1]=5;
			   face[sitex][sitey+2]=2;
			   sitey++;
		   }
		else
			if(face[sitex][sitey]==5)
			{
				face[sitex][sitey]=4;
				face[sitex][sitey+1]=5;
				face[sitex][sitey+2]=2;
				sitey++;
			}CPushBoxDlg::draw_game_face(dc);num_step++;break;
	case 3:break;
	case 4:if(face[sitex][sitey]==3)//人时
		   {
			   face[sitex][sitey]=1;
			   face[sitex][sitey+1]=5;
			   face[sitex][sitey+2]=6;
			   sitey++;
		   }
		else
			if(face[sitex][sitey]==5)
			{
				face[sitex][sitey]=4;
				face[sitex][sitey+1]=5;
				face[sitex][sitey+2]=6;
				sitey++;
			}CPushBoxDlg::draw_game_face(dc);num_step++;
			break;
	case 5:break;
	case 6:break;
		   }
		break;
	default:break;
	}						
	
}
void CPushBoxDlg::move_left()
{
	switch(face[sitex-1][sitey])
	{
	case 0:break;//遇到墙
	case 1:if(face[sitex][sitey]==3)
		   {
			   face[sitex][sitey]=1;
			   sitex-=1;
			   face[sitex][sitey]=3;
		   }
		else
			if(face[sitex][sitey]==5)
			{
				face[sitex][sitey]=4;
				sitex-=1;
				face[sitex][sitey]=3;
			}CPushBoxDlg::draw_game_face(dc);num_step++;
			break;
	case 2:switch(face[sitex-2][sitey])
		   {
	case 0:break;
	case 1:if(face[sitex][sitey]==3)
		   {
			   face[sitex][sitey]=1;
			   face[sitex-1][sitey]=3;
			   face[sitex-2][sitey]=2;
			   sitex-=1;
		   }
							 else
								 if(face[sitex][sitey]==5)
								 {
									 face[sitex][sitey]=4;
									 face[sitex-1][sitey]=3;
									 face[sitex-2][sitey]=2;
									 sitex-=1;
								 }CPushBoxDlg::draw_game_face(dc);num_step++;break;
	case 2:break;
	case 3:break;
	case 4:if(face[sitex][sitey]==3)//人时
		   {
			   face[sitex][sitey]=1;
			   face[sitex-1][sitey]=3;
			   face[sitex-2][sitey]=6;
			   sitex-=1;
		   }
		else
			if(face[sitex][sitey]==5)
			{
				face[sitex][sitey]=4;
				face[sitex-1][sitey]=3;
				face[sitex-2][sitey]=6;
				sitex-=1;
			}CPushBoxDlg::draw_game_face(dc);num_step++;break;
			
	case 5:break;
	case 6:break;
		   } 
		break;
	case 3:break;
	case 4:if(face[sitex][sitey]==3)//人时
		   {
			   face[sitex][sitey]=1;
			   sitex-=1;
			   face[sitex][sitey]=5;
		   }
		else
			if(face[sitex][sitey]==5)
			{
				face[sitex][sitey]=4;
				sitex-=1;
				face[sitex][sitey]=5;
			}CPushBoxDlg::draw_game_face(dc);num_step++;
			break;
	case 5:break;
	case 6:switch(face[sitex-2][sitey])
		   {
	case 0:break;
	case 1:if(face[sitex][sitey]==3)//人时
		   {
			   face[sitex][sitey]=1;
			   face[sitex-1][sitey]=5;
			   face[sitex-2][sitey]=2;
			   sitex--;
		   }
		else
			if(face[sitex][sitey]==5)
			{
				face[sitex][sitey]=4;
				face[sitex-1][sitey]=5;
				face[sitex-2][sitey]=2;
				sitex--;
			}CPushBoxDlg::draw_game_face(dc);num_step++;break;
	case 3:break;
	case 4:if(face[sitex][sitey]==3)//人时
		   {
			   face[sitex][sitey]=1;
			   face[sitex-1][sitey]=5;
			   face[sitex-2][sitey]=6;
			   sitex--;
		   }
		else
			if(face[sitex][sitey]==5)
			{
				face[sitex][sitey]=4;
				face[sitex-1][sitey]=5;
				face[sitex-2][sitey]=6;
				sitex--;
			}CPushBoxDlg::draw_game_face(dc);num_step++;break;
	case 5:break;
	case 6:break;
		   } 
		break;
	default:break;
	}						
}
void CPushBoxDlg::move_right()
{
	switch(face[sitex+1][sitey])
	{
	case 0:break;//遇到墙
	case 1:if(face[sitex][sitey]==3)
		   {
			   face[sitex][sitey]=1;
			   sitex+=1;
			   face[sitex][sitey]=3;
		   }
		else
			if(face[sitex][sitey]==5)
			{
				face[sitex][sitey]=4;
				sitex+=1;
				face[sitex][sitey]=3;
			}CPushBoxDlg::draw_game_face(dc);num_step++;
			break;
	case 2:switch(face[sitex+2][sitey])
		   {
	case 0:break;
	case 1:if(face[sitex][sitey]==3)
		   {
			   face[sitex][sitey]=1;
			   face[sitex+1][sitey]=3;
			   face[sitex+2][sitey]=2;
			   sitex+=1;
		   }
							 else
								 if(face[sitex][sitey]==5)
								 {
									 face[sitex][sitey]=4;
									 face[sitex+1][sitey]=3;
									 face[sitex+2][sitey]=2;
									 sitex+=1;
								 }CPushBoxDlg::draw_game_face(dc);num_step++;break;
	case 2:break;
	case 3:break;
	case 4:if(face[sitex][sitey]==3)//人时
		   {
			   face[sitex][sitey]=1;
			   face[sitex+1][sitey]=3;
			   face[sitex+2][sitey]=6;
			   sitex+=1;
		   }
		else
			if(face[sitex][sitey]==5)
			{
				face[sitex][sitey]=4;
				face[sitex+1][sitey]=3;
				face[sitex+2][sitey]=6;
				sitex+=1;
			}CPushBoxDlg::draw_game_face(dc);num_step++;break;
			
	case 5:break;
	case 6:break;
		   } 
		break;
	case 3:break;
	case 4:if(face[sitex][sitey]==3)//人时
		   {
			   face[sitex][sitey]=1;
			   sitex+=1;
			   face[sitex][sitey]=5;
		   }
		else
			if(face[sitex][sitey]==5)
			{
				face[sitex][sitey]=4;
				sitex+=1;
				face[sitex][sitey]=5;
			}CPushBoxDlg::draw_game_face(dc);num_step++;
			break;
	case 5:break;
	case 6:switch(face[sitex+2][sitey])
		   {
	case 0:break;
	case 1:if(face[sitex][sitey]==3)//人时
		   {
			   face[sitex][sitey]=1;
			   face[sitex+1][sitey]=5;
			   face[sitex+2][sitey]=2;
			   sitex++;
		   }
		else
			if(face[sitex][sitey]==5)
			{
				face[sitex][sitey]=4;
				face[sitex+1][sitey]=5;
				face[sitex+2][sitey]=2;
				sitex++;
			}CPushBoxDlg::draw_game_face(dc);num_step++;break;
	case 3:break;
	case 4:if(face[sitex][sitey]==3)//人时
		   {
			   face[sitex][sitey]=1;
			   face[sitex+1][sitey]=5;
			   face[sitex+2][sitey]=6;
			   sitex++;
		   }
		else
			if(face[sitex][sitey]==5)
			{
				face[sitex][sitey]=4;
				face[sitex+1][sitey]=5;
				face[sitex+2][sitey]=6;
				sitex++;
			}CPushBoxDlg::draw_game_face(dc);num_step++;break;
	case 5:break;
	case 6:break;
		   } 
		break;
	default:break;
	}						
}

这样游戏的主体已经完成了

 
  
 
  
 
  
 
 

你可能感兴趣的:(自己动手写推箱子游戏——界面(源码))