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; } }
這樣遊戲的主體已經完成了