直接上游戏效果 开发环境搭建我看网上好多制作贪吃蛇的帖子都是对刚学习C语言的同学们很不友好,制作的都是控制台,黑窗口的贪吃蛇游戏,能做出来但是感觉很无趣,不太像正常的游戏,接下来我将制作完全制作一款有趣的C语言贪吃蛇游戏
小伙伴们首先应该学会 工欲善其事必先利其器
- 开发工具VC 6.0 或 使用VS2010 Express即可
- 下载C语言的EasyX图形库
注解1:
首先为啥用VC/VS2010 Express,这两个开发工具兼容C语言的EasyX库,不要在乎工具有多老,和项目最搭配的才是最好的,就像我以前使用Turbe C开发过游戏一样,适合就好。
注解2:
直接面向百度,不了解的小伙伴可以自己查查EasyX是个啥,然后第一条链接是下载的官网里面有任何你想要学习的内容,很多程序员开发的游戏可以学习:
我这里下载的是Vs2010 Express,然后使用图形库的api来开发游戏
- 制作蛇通过结构体描述
- 制作地图通过结构体描述
- 制作随机产生食物
- 蛇能通过上下左右移动、能穿墙、不能撞自己
- 蛇吃到食物长一节身体
img保存了所有使用的图片素材
music游戏中使用的音乐、音效
snake.cpp就是这个游戏的代码了
img内容如下
music内容如下
首先导入所用到的头文件
#include#include #include #include #pragma comment(lib, "winmm.lib")
再声明好整个项目所用到的所有函数,这里我做了一个具体的思考过后,所用到的函数如下:
void move(); void body(); void wall(); void eat(); void kill(); void gameOver(); void reGame(); void stop(); void gameWin();
然后定义游戏中所用到的所有数据结构,代码如下:
struct BODYXY
{
int x;
int y;
};
struct snake
{
int x;
int y;
int width;
int height;
bool life;
int drection; //1上 2右 3下 4左
int body;
BODYXY bodyxy[215];
};
struct foods
{
bool needcreate;
int x;
int y;
};
struct MAP
{
int x;
int y;
};
定义好游戏中所有用到的全局变量,代码如下:
snake s; foods f; IMAGE bodyimg; IMAGE foodimg; IMAGE continueimg; MOUSEMSG m; #define WIDTH 900 //屏幕宽高900*600 #define HEIGHT 600 MAP map[12][18]; bool gameover = false; bool stopgame = false;
这里图形库中播放音乐使用代码如下:
PlaySound("music/game_music.wav", NULL, SND_ASYNC | SND_LOOP);
输出图片的代码如下:
putimage(50*j,50*i,&background);
循环播放SND_LOOP
游戏延迟的代码如下:
Sleep(250);
键盘控制上下左右代码如下:
if(kbhit())
{flag = getch();
if(flag == 224)
{flag = getch();
if(flag == 72 && s.drection != 3) //上
{
s.drection = 1;
}
if(flag == 80 && s.drection != 1) //下
{
s.drection = 3;
}
if(flag == 75 && s.drection != 2) //左
{
s.drection = 4;
}
if(flag == 77 && s.drection != 4) //右
{
s.drection = 2;
}
}
在游戏地图中,是分成每个块每个块的,所以我们让游戏跑起来之前必先要做的一件事就是开发地图,详细原理如下图:
实现的地图每个块的算法大概就是,如下代码:
for(int i=0;i<12;i++)
{
for(int j=0;j<18;j++)
{
map[i][j].x = 50*j;
map[i][j].y = 50*i;
}
}
游戏内所有属性的初始化
//初始化蛇属性
s.x = map[11][9].x;
s.y = map[11][9].y;
s.width = 50;
s.height = 50;
s.life = true;
s.drection = 1;
s.body = 1;
for(int i=0;i<215;i++)
{
s.bodyxy[i].x = -10000;
s.bodyxy[i].y = -10000;
}
f.needcreate = true;
f.x = -100000;
f.y = -100000;
//绘制背景
initgraph(WIDTH,HEIGHT);
IMAGE background;
loadimage(&background,_T("img/rectbg3.png"));
//绘制蛇头
IMAGE head;
loadimage(&head,_T("img/snake_head2.png"));
loadimage(&bodyimg,_T("img/snake_body.png"));
loadimage(&foodimg,_T("img/addblood2.png"));
loadimage(&continueimg,_T("img/continue.png"));
主体函数代码如下:
while(true)
{
int flag;
if(kbhit())
{flag = getch();
if(flag == 224)
{flag = getch();
if(flag == 72 && s.drection != 3) //上
{
s.drection = 1;
}
if(flag == 80 && s.drection != 1) //下
{
s.drection = 3;
}
if(flag == 75 && s.drection != 2) //左
{
s.drection = 4;
}
if(flag == 77 && s.drection != 4) //右
{
s.drection = 2;
}
}
if(gameover)
{
if(flag == 32)
{
reGame();
}
}
else if(flag == 32)
{
//暂停
stop();
}
}
if(!gameover && !stopgame)
{
//绘制游戏背景
for(int i=0;i<12;i++)
{
for(int j=0;j<18;j++)
{
putimage(50*j,50*i,&background);
}
}
//移动蛇
move();
//碰撞
eat();
//蛇头
putimage(s.x,s.y,&head);
//蛇身体
body();
//食物
if(f.needcreate == false){
putimage(f.x,f.y,&foodimg);
}
//是否自杀
kill();
//gameover
if(gameover == true)
{
gameOver();
}
//win
if(s.body >= 215)
{
gameover = true;
gameWin();
}
wall();
}
Sleep(250);
}
绘制游戏主体函数,代码如下:
void body()
{
//绘制body
for(int i=0;i
putimage(s.bodyxy[i].x,s.bodyxy[i].y,&bodyimg);
}
}
蛇具体移动函数,代码如下:
void move()
{
//循环得到前一个body
int prx,pry;
for(int i=s.body-1;i>0;i--)
{
s.bodyxy[i].x = s.bodyxy[i-1].x;
s.bodyxy[i].y = s.bodyxy[i-1].y;
}
s.bodyxy[0].x = s.x;
s.bodyxy[0].y = s.y;
if(s.drection == 1)
{
s.y-=50;
}
else if(s.drection == 2)
{
s.x+=50;
}
else if(s.drection == 3)
{
s.y+=50;
}
else if(s.drection == 4)
{
s.x-=50;
}
}
撞墙后,让蛇从另一边穿过,具体代码如下:
void wall()
{
//上方
if(s.y+50 < 0)
{
s.y = HEIGHT - 50;
}
//上方
if(s.y+50 > HEIGHT)
{
s.y = 0;
}
//左方
if(s.x+50 < 0)
{
s.x = WIDTH - 50;
}
//右方
if(s.x+50 > WIDTH)
{
s.x = 0;
}
}
吃到食物后的具体函数,代码如下:
void eat()
{
int sx = s.x + s.width/2;
int sy = s.y + s.height/2;
if(sx >= f.x && sx <= f.x + 50)
if(sy >= f.y && sy <= f.y + 50)
{
f.needcreate = true;
s.body++;
}
if(f.needcreate == true)
{
srand((unsigned)time(NULL));
int ri = (int)(rand()%12);
int rj = (int)(rand()%18);
f.x = map[ri][rj].x;
f.y = map[ri][rj].y;
f.needcreate = false;
}
}
吃到食物后,也就是碰撞到食物后让食物继续创建,通过needcreate这个枚举变量来操作,通过rand()函数实现让食物随机出现在地图上某个位置。
如果蛇碰到了自己就执行游戏结束,代码如下:
void kill()
{
int sx = s.x + s.width/2;
int sy = s.y + s.height/2;
for(int i=0;i
if(sx >= s.bodyxy[i].x && sx <= s.bodyxy[i].x + 50)
if(sy >= s.bodyxy[i].y && sy <= s.bodyxy[i].y + 50)
{
gameover = true;
break;
}
}
}
制作游戏结束音效和页面,代码如下:
void gameOver()
{
PlaySound("music/game_over.wav", NULL, SND_ASYNC);
putimage(WIDTH/2-150,HEIGHT/2-150,&continueimg);
}
继续游戏,然后初始化数据,代码如下:
void continueGame()
{
//初始化蛇属性
s.x = map[11][9].x;
s.y = map[11][9].y;
s.width = 50;
s.height = 50;
s.life = true;
s.drection = 1;
s.body = 1;
for(int i=0;i<215;i++)
{
s.bodyxy[i].x = -10000;
s.bodyxy[i].y = -10000;
}
f.needcreate = true;
f.x = -100000;
f.y = -100000;
}
游戏胜利的音效和页面,代码如下:
void gameWin()
{
PlaySound("music/win.wav", NULL, SND_ASYNC);
putimage(WIDTH/2-150,HEIGHT/2-150,&continueimg);
}
重新游戏,代码如下:
void reGame()
{
gameover = false;
//初始化蛇属性
s.x = map[11][9].x;
s.y = map[11][9].y;
s.width = 50;
s.height = 50;
s.life = true;
s.drection = 1;
s.body = 1;
for(int i=0;i<215;i++)
{
s.bodyxy[i].x = -10000;
s.bodyxy[i].y = -10000;
}
f.needcreate = true;
f.x = -100000;
f.y = -100000;
PlaySound("music/game_music.wav", NULL, SND_ASYNC | SND_LOOP);
}
暂停游戏,代码如下:
void stop()
{
stopgame = !stopgame;
PlaySound("music/stop.wav", NULL, SND_ASYNC);
if(stopgame == false)
{
PlaySound("music/game_music.wav", NULL, SND_ASYNC | SND_LOOP);
}
}
整个游戏的代码如下:
#include#include #include #include #pragma comment(lib, "winmm.lib") void move(); void body(); void wall(); void eat(); void kill(); void gameOver(); void reGame(); void stop(); void gameWin(); struct BODYXY { int x; int y; }; struct snake { int x; int y; int width; int height; bool life; int drection; //1上 2右 3下 4左 int body; BODYXY bodyxy[215]; }; struct foods { bool needcreate; int x; int y; }; struct MAP { int x; int y; }; snake s; foods f; IMAGE bodyimg; IMAGE foodimg; IMAGE continueimg; MOUSEMSG m; #define WIDTH 900 #define HEIGHT 600 MAP map[12][18]; bool gameover = false; bool stopgame = false; int main() { PlaySound("music/game_music.wav", NULL, SND_ASYNC | SND_LOOP); for(int i=0;i<12;i++) { for(int j=0;j<18;j++) { map[i][j].x = 50*j; map[i][j].y = 50*i; } } //初始化蛇属性 s.x = map[11][9].x; s.y = map[11][9].y; s.width = 50; s.height = 50; s.life = true; s.drection = 1; s.body = 1; for(int i=0;i<215;i++) { s.bodyxy[i].x = -10000; s.bodyxy[i].y = -10000; } f.needcreate = true; f.x = -100000; f.y = -100000; //绘制背景 initgraph(WIDTH,HEIGHT); IMAGE background; loadimage(&background,_T("img/rectbg3.png")); //绘制蛇头 IMAGE head; loadimage(&head,_T("img/snake_head2.png")); loadimage(&bodyimg,_T("img/snake_body.png")); loadimage(&foodimg,_T("img/addblood2.png")); loadimage(&continueimg,_T("img/continue.png")); while(true) { int flag; if(kbhit()) {flag = getch(); if(flag == 224) {flag = getch(); if(flag == 72 && s.drection != 3) //上 { s.drection = 1; } if(flag == 80 && s.drection != 1) //下 { s.drection = 3; } if(flag == 75 && s.drection != 2) //左 { s.drection = 4; } if(flag == 77 && s.drection != 4) //右 { s.drection = 2; } } if(gameover) { if(flag == 32) { reGame(); } } else if(flag == 32) { //暂停 stop(); } } if(!gameover && !stopgame) { //绘制游戏背景 for(int i=0;i<12;i++) { for(int j=0;j<18;j++) { putimage(50*j,50*i,&background); } } //移动蛇 move(); //碰撞 eat(); //蛇头 putimage(s.x,s.y,&head); //蛇身体 body(); //食物 if(f.needcreate == false){ putimage(f.x,f.y,&foodimg); } //是否自杀 kill(); //gameover if(gameover == true) { gameOver(); } //win if(s.body >= 215) { gameover = true; gameWin(); } wall(); } Sleep(250); } _getch(); closegraph(); return 0; } void body() { //绘制body for(int i=0;i putimage(s.bodyxy[i].x,s.bodyxy[i].y,&bodyimg); } } void move() { //循环得到前一个body int prx,pry; for(int i=s.body-1;i>0;i--) { s.bodyxy[i].x = s.bodyxy[i-1].x; s.bodyxy[i].y = s.bodyxy[i-1].y; } s.bodyxy[0].x = s.x; s.bodyxy[0].y = s.y; if(s.drection == 1) { s.y-=50; } else if(s.drection == 2) { s.x+=50; } else if(s.drection == 3) { s.y+=50; } else if(s.drection == 4) { s.x-=50; } } void wall() { //上方 if(s.y+50 < 0) { s.y = HEIGHT - 50; } //上方 if(s.y+50 > HEIGHT) { s.y = 0; } //左方 if(s.x+50 < 0) { s.x = WIDTH - 50; } //右方 if(s.x+50 > WIDTH) { s.x = 0; } } void eat() { int sx = s.x + s.width/2; int sy = s.y + s.height/2; if(sx >= f.x && sx <= f.x + 50) if(sy >= f.y && sy <= f.y + 50) { f.needcreate = true; s.body++; } if(f.needcreate == true) { srand((unsigned)time(NULL)); int ri = (int)(rand()%12); int rj = (int)(rand()%18); f.x = map[ri][rj].x; f.y = map[ri][rj].y; f.needcreate = false; } } void kill() { int sx = s.x + s.width/2; int sy = s.y + s.height/2; for(int i=0;i if(sx >= s.bodyxy[i].x && sx <= s.bodyxy[i].x + 50) if(sy >= s.bodyxy[i].y && sy <= s.bodyxy[i].y + 50) { gameover = true; break; } } } void gameOver() { PlaySound("music/game_over.wav", NULL, SND_ASYNC); putimage(WIDTH/2-150,HEIGHT/2-150,&continueimg); } void continueGame() { //初始化蛇属性 s.x = map[11][9].x; s.y = map[11][9].y; s.width = 50; s.height = 50; s.life = true; s.drection = 1; s.body = 1; for(int i=0;i<215;i++) { s.bodyxy[i].x = -10000; s.bodyxy[i].y = -10000; } f.needcreate = true; f.x = -100000; f.y = -100000; } void gameWin() { PlaySound("music/win.wav", NULL, SND_ASYNC); putimage(WIDTH/2-150,HEIGHT/2-150,&continueimg); } void reGame() { gameover = false; //初始化蛇属性 s.x = map[11][9].x; s.y = map[11][9].y; s.width = 50; s.height = 50; s.life = true; s.drection = 1; s.body = 1; for(int i=0;i<215;i++) { s.bodyxy[i].x = -10000; s.bodyxy[i].y = -10000; } f.needcreate = true; f.x = -100000; f.y = -100000; PlaySound("music/game_music.wav", NULL, SND_ASYNC | SND_LOOP); } void stop() { stopgame = !stopgame; PlaySound("music/stop.wav", NULL, SND_ASYNC); if(stopgame == false) { PlaySound("music/game_music.wav", NULL, SND_ASYNC | SND_LOOP); } }
代码量总共三百多行实现了一个小游戏


![[C语言] 自制的贪吃蛇游戏 [C语言] 自制的贪吃蛇游戏](http://www.mshxw.com/aiimages/31/1030335.png)
