自己動手寫推箱子游戲——介面(原始碼)
阿新 • • 發佈:2019-02-07
MFC開發自己的推箱子游戲
第一:推箱子游戲的主介面
遊戲的主介面其實就是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; } }
這樣遊戲的主體已經完成了