基于EasyX的推箱子游戲
一、預備知識
1.使用EasyX必須要知道的一些基礎函式
2.選擇結構 if , switch
3.回圈結構 for, while
4.多維陣列 arr1[N], arr2[N][N] , arr3[N][N][N]
5.函式封裝
二、游戲邏輯
想要寫出推箱子,首先要知道推箱子游戲都有哪些元素和規則
1.推箱子元素

1.小人 2.箱子 3.空地 4.墻壁 5.目的地 6.到達目的地的箱子
2.推箱子規則
1.“小人”只能在“空地”和“目的地”上行走
2.“小人”可以推“箱子后面是 ‘空地’和‘目的地’ ”的“箱子”
3.所有“箱子”到達“目的地”游戲獲勝
三、游戲設計
知道游戲元素和規則就可以開始設計游戲了
1.地圖設計
首選需要知道的是,游戲地圖是一個二維陣列
根據玩推箱子的經驗可以知道,游戲中會出現哪些組合情況
- “小人”在“目的地”
- “箱子”在“目的地”
下面我們給這些情況定義一些變數,數字大家可以隨意,對應就好
enum material
{
space=0,//空地
wall=1,//墻壁
box=3, //箱子
person=4,//小人
aim=5,//目的地
box_aim=8,//箱子在目的地 3+5=8
person_aim=9,//小人在目的地 4+5=9
};
元素和數字已經對應起來了,先寫一個初始化加載圖片函式Loadimg(),素材就放在源檔案旁邊
#define SIZE 35//每個元素的大小
IMAGE img[10];//存放小圖片
void Loadimg()//加載資源
{
loadimage(&img[0],L"./images/0.jpg",SIZE,SIZE);//空地
loadimage(&img[1],L"./images/1.jpg",SIZE,SIZE);//墻壁
loadimage(&img[3],L"./images/3.jpg",SIZE,SIZE);//箱子
loadimage(&img[4],L"./images/4.jpg",SIZE,SIZE);//小人
loadimage(&img[5],L"./images/5.jpg",SIZE,SIZE);//目的地
loadimage(&img[8],L"./images/8.jpg",SIZE,SIZE);//箱子在目的地
}
然后你就知道為什么游戲地圖是一個二維陣列

是不是switch,case根據數字貼圖就完事了,就是這么easy,一關怎么能行呢,當然要很多關,二維不夠三維來湊,定義一個全域變數map三維陣列,和全域變數number存放關卡數
int number=0;//存放關卡數,當前第一關
int map[3][7][7]=
{ //第一關
1,1,1,1,1,1,1,
1,5,0,0,0,5,1,
1,0,3,0,3,0,1,
1,0,0,4,0,0,1,
1,0,3,0,3,0,1,
1,5,0,0,0,5,1,
1,1,1,1,1,1,1,
//第二關
1,1,1,1,1,1,1,
1,5,5,5,5,5,1,
1,0,0,3,0,0,1,
1,0,3,3,3,0,1,
1,0,0,3,0,0,1,
1,0,0,4,0,0,1,
1,1,1,1,1,1,1,
//第三關
1,1,1,1,1,1,1,
1,0,0,0,0,0,1,
1,5,1,5,1,3,1,
1,0,3,0,5,0,1,
1,3,1,3,1,0,1,
1,4,0,0,0,5,1,
1,1,1,1,1,1,1,
};
地圖定義好了,那就貼圖吧,寫一個Drawmap()函式畫地圖
#define ROWS 7//行數
#define COLS 7//列數
void Drawmap()
{
int i,j,x,y;
for (i = 0; i < ROWS; i++)
{
for (j = 0; j < COLS; j++)
{
x=0;y=0;
x += j * SIZE, y += i * SIZE;//確定每個圖片的坐標
switch (map[number][i][j])
{
case space://空地
putimage(x, y, &img[space]);
break;
case wall://墻壁
putimage(x, y, &img[wall]);
break;
case box://箱子
putimage(x, y, &img[box]);
break;
case person://小人
putimage(x, y, &img[person]);
break;
case aim://目的地
putimage(x, y, &img[aim]);
break;
case box_aim://箱子在目的地
putimage(x, y, &img[box_aim]);
break;
case person_aim://人在目的地還是人
putimage(x, y, &img[person]);
break;
}
}
printf("\n");
}
system("cls");//清屏
}
2.移動設計
上文提到
1.“小人”只能在“空地”和“目的地”上行走
2.“小人”可以推“箱子后面是 ‘空地’和‘目的地’ ”的“箱子”
那么每次移動完都需要確定小人的位置,再判斷能否移動
先定義全域變數記錄小人位置,再寫一個獲取小人位置的函式Getpersonxy()
int ipos,jpos;//記錄小人位置
void Getpersonxy()
{
int i,j;
for (i = 0; i < ROWS; i++)
{
for (j = 0; j < COLS; j++)
{
if(map[number][i][j]==person || map[number][i][j]==person_aim)
{//找到小人 或者 小人在目的地
ipos=i;
jpos=j;//找到小人位置
break;
}
}
}
}
找到小人位置后判斷小人是否能移動,寫一個Moveperson()函式,這個就要劃重點了
void Moveperson()
{
PlaySound(L"./images/move.wav", nullptr, SND_FILENAME | SND_ASYNC);//播放移動音樂
char ch = _getch();
switch (ch)//控制小人走
{
case 'w':
case 'W':
case 72://小鍵盤鍵值
if (map[number][ipos-1][jpos] == space || map[number][ipos-1][jpos] == aim)
{//人前面是空地或者目的地
map[number][ipos-1][jpos]+=person;//人來了
map[number][ipos][jpos]-=person;//人走了
}
else if (map[number][ipos-1][jpos] == box || map[number][ipos-1][jpos] == box_aim)
{//人前面是箱子或者箱子在目的地
//判斷箱子是否能走
if (map[number][ipos-2][jpos] == space || map[number][ipos-2][jpos] == aim)//箱子前面是空地或者目的地 才能走
{
map[number][ipos-2][jpos]+=box ; //箱子來了
map[number][ipos-1][jpos]+=person-box ;//人來了 箱子走了
map[number][ipos][jpos]-=person;//人走了
}
}
break;
case 's':
case 'S':
case 80://小鍵盤鍵值
if (map[number][ipos+1][jpos] == space || map[number][ipos+1][jpos] == aim)
{//人前面是空地或者目的地
map[number][ipos+1][jpos]+=person;//人來了
map[number][ipos][jpos]-=person;//人走了
}
else if (map[number][ipos+1][jpos] == box || map[number][ipos+1][jpos] == box_aim)
{//人前面是箱子或者箱子在目的地
//判斷箱子是否能走
if (map[number][ipos+2][jpos] == space || map[number][ipos+2][jpos] == aim)//箱子前面是空地或者目的地 才能走
{
map[number][ipos+2][jpos]+=box ; //箱子來了
map[number][ipos+1][jpos]+=person-box;//人來了 箱子走了
map[number][ipos][jpos]-=person;//人走了
}
}
break;
case 'a':
case 'A':
case 75://小鍵盤鍵值
if (map[number][ipos][jpos-1] == space || map[number][ipos][jpos-1] == aim)
{//人前面是空地或者目的地
map[number][ipos][jpos-1]+= person;//人來了
map[number][ipos][jpos]-= person;//人走了
}
else if (map[number][ipos][jpos-1] == box || map[number][ipos][jpos-1] == box_aim)
{//人前面是箱子或者箱子在目的地
//判斷箱子是否能走
if (map[number][ipos][jpos-2] == space || map[number][ipos][jpos-2] == aim)//箱子前面是空地或者目的地 才能走
{
map[number][ipos][jpos-2]+=box ; //箱子來了
map[number][ipos][jpos-1]+=person-box ;//人來了 箱子走了
map[number][ipos][jpos]-=person;//人走了
}
}
break;
case 'd':
case 'D':
case 77://小鍵盤鍵值
if (map[number][ipos][jpos+1] == space || map[number][ipos][jpos+1] == aim)
{//人前面是空地或者目的地
map[number][ipos][jpos+1]+=person;//人來了
map[number][ipos][jpos]-=person;//人走了
}
else if (map[number][ipos][jpos+1] == box || map[number][ipos][jpos+1] == box_aim)
{//人前面是箱子或者箱子在目的地
//判斷箱子是否能走
if (map[number][ipos][jpos+2] == space || map[number][ipos][jpos+2] == aim)//箱子前面是空地或者目的地 才能走
{
map[number][ipos][jpos+2]+=box ; //箱子來了
map[number][ipos][jpos+1]+=person-box ;//人來了 箱子走了
map[number][ipos][jpos]-=person;//人走了
}
}
break;
}
}
3.結束設計
上文提到
3.所有“箱子”到達“目的地”游戲獲勝**
也就是判斷地圖上是否有box,如果有,游戲繼續,沒有box,進入下一關,寫一個Gameover()函式
int Gameover()
{
int i, j;
for (i = 0; i < ROWS; i++)
{
for (j = 0; j < COLS; j++)
{
//遍歷地圖是否有箱子
if (map[number][i][j] == box)
{
return 0;//有箱子退出回圈 繼續
}
}
}
return 1;
}
4.整體設計
下面把上面的函陣列合起來就是推箱子游戲,再來點音樂
#include<stdio.h>
#include<easyx.h>//圖形庫
#include<conio.h>//按鍵
#include<mmsystem.h>//音樂
#pragma comment(lib,"winmm.lib")//庫檔案
int main()
{
initgraph(SIZE*7,SIZE*7);//創建地圖大小的視窗
Loadimg();//加載資源
//回圈播放背景音樂
mciSendString(L"open ./images/bg.mp3 ", 0, 0, 0);
mciSendString(_T("play ./images/bg.mp3 repeat"), 0, 0, 0);
while(true){
//繪制界面
BeginBatchDraw();
Drawmap();//貼地圖
EndBatchDraw();
if (Gameover())
{
PlaySound(L"./images/success.wav", nullptr, SND_FILENAME | SND_ASYNC);//播放勝利音樂
number++;//進入下一關
Sleep(500);
if (number>= 3)
break;//第三關玩完結束
}
if (_kbhit())//獲取按鍵訊息
{
Getpersonxy();//找到小人位置
Moveperson();//小人移動
}
}
mciSendString(L"close ./images/bg.mp3",0,0,0);//關閉背景音樂
setbkmode(0);//設定文字背景透明
settextcolor(RGB(167, 48, 48));//設定字體顏色
settextstyle(30, 0, _T("宋體"));//64是字體大小 0是自適應 雙引號里可以填字體名字
outtextxy(0, 110, _T("游戲結束,你真棒!"));
Sleep(5000);
closegraph();//關閉視窗
return 0;
}
把上面所有代碼復制到一個cpp檔案里,再把素材改好命名放到images檔案夾里,images檔案夾在cpp檔案旁邊,就可以編譯運行了!
圖片音樂素材及可執行程式都在我的資源中,需要的可以進行下載
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/291124.html
標籤:其他
上一篇:EasyX必會基礎
