基于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.食物
有了素材,首先拿數字對應起來,再來一個加載資源函式Loadimg()
#define SIZE 25
IMAGE img[8];//存放圖片變數
enum element
{
space=0,//空地
food=-4,//食物
wall=-1,//墻壁
head=1, //蛇頭
move_rt=1,//向右
move_dw=2,//向下
move_lt=3,//向左
move_up=4,//向上
};
void Loadimg()
{
loadimage(&img[0],L"./images/0.jpg",SIZE,SIZE);
loadimage(&img[1],L"./images/1.jpg",SIZE,SIZE);
loadimage(&img[2],L"./images/2.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[6],L"./images/6.jpg",SIZE,SIZE);
loadimage(&img[7],L"./images/7.jpg",SIZE,SIZE);
}
2.貪吃蛇規則
1.按鍵可以改變蛇上、下、左、右移動
2.蛇默認沿當前方向移動
3.蛇吃到食物身體邊長
4.蛇撞到墻或者自己的身體游戲結束
三、游戲設計
知道游戲元素和規則就可以開始設計游戲了
1.地圖設計
地圖是一個二維陣列,蛇的身體一次用1,2,3,4表示,-1表示墻壁,0表示空地
#define NUM 21
int map[NUM][NUM]=
{
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,
-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,
-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,
-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,
-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,
-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,
-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,
-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,
-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,
-1, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,
-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,
-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,
-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,
-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,
-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,
-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,
-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,
-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,
-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1,
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
};
地圖初始化好了,開始貼圖,根據移動方向的不同,貼不同的蛇頭,寫個Drawmap()函式
int move=1;//默認向右移動,1向右移動,2向下,3向左,4向右
void Drawmap()
{
for(int i=0;i<NUM;i++)
{
for(int j=0;j<NUM;j++)
{
if(map[i][j]==wall)//貼墻
putimage(j*SIZE,i*SIZE,&img[6]);
else if(map[i][j]>1)//貼身
putimage(j*SIZE,i*SIZE,&img[0]);
else if(map[i][j]==food)//貼食物
putimage(j*SIZE,i*SIZE,&img[7]);
else if(map[i][j]==head)//貼頭
if(move==move_rt)//向右移動
putimage(j*SIZE,i*SIZE,&img[move_rt]);
else if(move==move_dw)//向下移動
putimage(j*SIZE,i*SIZE,&img[move_dw]);
else if(move==move_lt)//向左移動
putimage(j*SIZE,i*SIZE,&img[move_lt]);
else if(move==move_up)//向上移動
putimage(j*SIZE,i*SIZE,&img[move_up]);
}
}
}
地圖上還需要有蛇吃的食物,用隨機函式產生食物,需要包含<time.h>,寫個產生食物函式Producefood()
void Producefood()//產生食物
{
srand((unsigned)time(NULL));//根據時間設定亂數種子
for(int k=0;k<1; )
{
int x=rand()%(NUM-4) +2;//生成2 ~ 18的亂數
int y=rand()%(NUM-4) +2;//為避免產生相同的坐標,采用下面的方式
if(map[x][y]==0)
{//如果是空地
map[x][y]=food;
k++;//食物設定成功才加加
}
}
}
2.移動設計
上文提到
1.按鍵可以改變蛇上、下、左、右移動
2.蛇默認沿當前方向移動
但是我們知道,蛇向某個方向移動的時候,不能往該方向的相反方向移動,寫一個函式Controlsnake()用鍵盤控制蛇移動
void Controlsnake()
{
char ch =_getch();
if( (ch=='w' || ch=='W' || ch==72) && move!=move_dw)
//如果想往上移動且現在不在向下移動
move=move_up;//向上移動
else if( (ch=='s' || ch=='S' || ch==80) && move!=move_up)
//如果想往下移動且現在不在向上移動
move=move_dw;//向下移動
else if( (ch=='a' || ch=='A' || ch==75) && move!=move_rt)
//如果想往左移動且現在不在向右移動
move=move_lt;//向左移動
else if( (ch=='d' || ch=='D' || ch==77) && move!=move_lt)
//如果想往右移動且現在不在向左移動
move=move_rt;//向右移動
}
上文提到
3.蛇吃到食物身體邊長
4.蛇撞到墻或者自己的身體游戲結束
下面就要劃重點了,我們如何讓蛇在二維陣列上移動呢?
此并非我自己想出來的,來源mooc,詳情見下方鏈接
假設小蛇元素為54321,其中1為蛇頭、5432為蛇身、最大值5為蛇尾,首先將所有大于0的元素加1,得到65432;將最大值6變為0,即去除了原來的蛇尾;再根據對應移動方向,將2對應方向的元素由0變成1;如此即實作了小蛇的移動,小蛇向上移動的雙應流程如圖3-14所示,

基于以上的描述,我們就可以寫出蛇的移動函式Snakemove()
int oldheadx,oldheady,newheadx,newheady,tailx,taily;
int score=0,speed=150;//當前得分,和蛇的移動速度,越小速度越快
TCHAR s[100];//存放訊息提示陳述句
void Snakemove()
{
//遍歷地圖把地圖上正數全+1
for(int i=0;i<NUM;i++)
{
for(int j=0;j<NUM;j++)
{
if(map[i][j]>0)
map[i][j]++;
}
}
//最大數是尾巴,找到最大數坐標,移動后變成0
int max=0;
for(int a=0;a<NUM;a++)
{
for(int b=0;b<NUM;b++)
{
if(map[a][b]==2)
{
oldheadx=a;
oldheady=b;//舊蛇頭坐標
}
if(map[a][b]>max)
{
max=map[a][b];
tailx=a;
taily=b;//蛇尾坐標
}
}
}
//根據移動方向計算新蛇頭坐標的位置
if(move==move_rt)//如果向右移動
{
newheadx=oldheadx;
newheady=oldheady+1;
}
else if(move==move_dw)//如果向下移動
{
newheadx=oldheadx+1;
newheady=oldheady;
}
else if(move==move_lt)//如果向左移動
{
newheadx=oldheadx;
newheady=oldheady-1;
}
else if(move==move_up)//如果向上移動
{
newheadx=oldheadx-1;
newheady=oldheady;
}
if(map[newheadx][newheady]==food)
{//如果吃到食物
PlaySound(L"./images/eat.wav", nullptr, SND_FILENAME | SND_ASYNC);//播放吃到食物音效
score++;//得分增加
Producefood();//產生新的食物
//尾部不變
}
else if(map[newheadx][newheady]==wall || map[newheadx][newheady]>0 )
{//如果撞墻或撞自己
mciSendString(_T("close ./images/bg.mp3"), 0, 0, 0);//關閉背景音樂
PlaySound(L"./images/over.wav", nullptr, SND_FILENAME | SND_ASYNC);//播放結束音效
_stprintf_s(s, _T("游戲結束,你的得分:%d分"), score);
MessageBox(NULL,s,_T("游戲提示"),MB_OK | MB_SYSTEMMODAL) ;//顯示得分
system("pause");
}
else
{//沒吃到食物 游戲沒結束
map[tailx][taily]=0;//尾巴變成0
}
map[newheadx][newheady]=1;//新的蛇頭是1
oldheadx=newheadx;
oldheady=newheady;//新頭坐標變為舊坐標
}
3.速度設計
我們用Sleep()函式來控制蛇移動的速度,寫一個根據得分改變速度函式Changespeed()
void Changespeed()
{
if(score>=5 && score<10)
speed=130;
else if(score>=10 && score<15)
speed=110;
else if(score>=15 && score<20)
speed=90;
else if(score>=20 && score<25)
speed=70;
else if(score>=25 && score<30)
speed=50;
else if(score>=30)
speed=30;
Sleep(speed);
}
4.整體設計
下面把上面的函陣列合起來就是貪吃蛇游戲,再來點音樂
#include<time.h>
#include<easyx.h>//圖形庫
#include<conio.h>//按鍵
#include<mmsystem.h>//音樂
#pragma comment(lib,"winmm.lib")//庫檔案
int main()
{
initgraph(NUM*SIZE,NUM*SIZE);//創建地圖大小的視窗
Loadimg();//加載資源
setbkcolor(WHITE);//設定背景白色
Producefood();//產生食物
//回圈播放背景音樂
mciSendString(L"open ./images/bg.mp3 ", 0, 0, 0);
mciSendString(_T("play ./images/bg.mp3 repeat"), 0, 0, 0);
while(true){
//繪制界面
BeginBatchDraw();//批量繪圖開始
cleardevice();//清理螢屏
Drawmap();//繪制地圖
EndBatchDraw();//批量繪圖結束
if (_kbhit())//獲取按鍵訊息
{
Controlsnake();//改變蛇的移動
}
Snakemove();//蛇默認移動
Changespeed();//根據得分改變速度
}
return 0;
}
把上面所有代碼復制到一個cpp檔案里,再把素材改好命名放到images檔案夾里,images檔案夾在cpp檔案旁邊,就可以編譯運行了!
圖片音樂素材及可執行程式都在我的資源中,需要的可以進行下載
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/291950.html
標籤:其他
上一篇:基于EasyX的五子棋游戲
