easyx图形库做贪吃蛇游戏
编程总是对着一个黑窗口,可以说是非常乏味了,于是喵喵就翻出来了以前用easyx图形库做图形界面的贪吃蛇游戏。
不过大家只是当做提高编程的乐趣来学习吧,想进一步做的话可以学习QT,还有其他的框架。
这是一个easyx图形库的学习教程,建议大家学完再看本文:
https://www.easyx.cn/skills/List.aspx?id=7
首先看一下效果图:


实现的功能:
基本的吃食物长大,撞墙死亡,特殊食物,游戏暂停,重开游戏,记分数的功能。
游戏最高分的记录。
游戏关卡的选择。
加了游戏的音效,具体的音效,可以在下面下载:
链接:https://pan.baidu.com/s/1NFn19J7gcXmG45jAuYe4Ig 密码:x5kz
一些说明:
这个程序用的基本是C,当时对C++类的理解实在太差,现在也懒的改了。
这个程序是万恶的VC写的,当时还没发现codeblocks啥的。
关于程序的功能实现,并不太难,有详细的注释,可以随意复制粘贴。
下面看贪吃蛇的代码:
#include "node.h"
class Food
{
public:
Food();
virtual ~Food();
int food;//0为无食物,1为有食物
node foodxy;
int c;//累计出现食物个数
}; Food::Food()
{
c=;
} Food::~Food()
{ } class node
{
public:
int x,y;
node();
virtual ~node(); };
#include "node.h"
class snake
{
public:
snake();
virtual ~snake();
node jie[];//蛇每个节点坐标
int n;//蛇当前节点数
char dry;//蛇当前前进方向
};
class wall
{
public:
node dry[];//障碍物的坐标
int n;//障碍物的个数
wall();
virtual ~wall(); };
#include<graphics.h>
#include<conio.h>
#include<time.h>
#include "snake.h"
#include "Food.h"
#include<stdio.h>
#include<fstream.h>
#include "mmsystem.h"//导入声音头文件
#pragma comment(lib,"winmm.lib")//导入声音头文件库
#include "wall.h"
int wallnum,speed; void zero();
void first();//操作页面初始化
int second( Food &, snake&);//数据初始化
void foodstyle(Food&,wall);//食物状态
void gameover(snake,int);//游戏结束
void judge( Food&,snake&,int,wall);//判断游戏是否结束
void judge2(Food &,snake&);//判断蛇是否吃到食物
void snakemove(Food&,snake&,wall);
void snakeshow(Food &,snake &,wall);
void change(Food &,snake &,int);//改变方向
void score(snake );//记录分数
void wallstyle(wall&);//障碍物的状态 int main()
{
initgraph(,);
int o;
Food F;
snake Snake;
wall Wall;
first();
zero();
o= second(F,Snake);
wallstyle(Wall);
PlaySound("kaichang.wav",NULL,SND_FILENAME|SND_ASYNC);//载入声音特效
while()
{
while(!kbhit())//没有键盘输入时
{ if(!F.food )
{
foodstyle(F,Wall);
}
judge(F,Snake,o,Wall);
judge2(F,Snake);
snakemove(F,Snake,Wall);
Sleep(speed);//控制速度
score(Snake);
}
change(F,Snake,o); }
return ;
} void zero()
{
char p[];
outtextxy(,,_T("关卡:"));
for(int i=;i<;i++)
{
RECT r= {+*i,,+*i,};//使数字显示在矩形区域中央
sprintf(p, "%d", i+);
drawtext(p, &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
}
settextstyle(, , _T("黑体"));
outtextxy(,,_T("请输入 1 or 2 or 3 确定关卡"));
char c=getch();//控制选择关卡
switch (c)
{
case '':
wallnum=;
speed=;
i=;
break;
case '':
wallnum=;
speed=;
i=;
break;
case '':
wallnum=;
speed=;
i=;
break;
default:
settextcolor(BLACK);//擦除
outtextxy(,,_T("请输入 1 or 2 or 3 确定关卡"));
settextcolor(RED);
outtextxy(,,_T("请正确输入"));
Sleep();//确保显示时间
main();
}
setfillcolor(GREEN);
RECT v= {+*(i-),,+*(i-),};
sprintf(p, "%d", i);
drawtext(p, &v, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
settextcolor(BLACK);
outtextxy(,,_T("请输入 1 or 2 or 3 确定关卡"));
settextcolor(RED);//确保以后的字体颜色
}
void first()
{
srand((unsigned)time(NULL));//播种子
setlinestyle(PS_DASH);//实线
settextcolor(RED);
setlinecolor(BLUE);
line(,,,);//分界线
line(,,,);
outtextxy(,,_T("分数:"));//操作说明
outtextxy(,,_T("最高分:"));
outtextxy(,,_T("操作方式:"));
outtextxy(,,_T(" W/w:上移 S/s:下移"));
outtextxy(,,_T(" A/a:左移 D/d:右移"));
outtextxy(,,_T(" 空格:暂停/开始"));
outtextxy(,,_T(" Esc:退出"));
outtextxy(,,_T(" 作者:丁喵喵"));
setlinecolor(BLUE);//示例图形
setfillcolor(GREEN);
fillcircle(,,);
fillcircle(,,);
setfillcolor(RED);
fillrectangle(,,,);
fillrectangle(,,,);
setfillcolor(BLACK);
fillcircle(,,);
outtextxy(,,_T("温馨提示:"));
outtextxy(,,_T("一.障碍物,撞击死亡"));
outtextxy(,,_T("四.被破坏障碍物,非无敌状态撞击仍会死亡"));
outtextxy(,,_T("二.特殊食物,吃掉冲撞障碍物不死亡"));
outtextxy(,,_T("三.蛇吃完特殊食物后的无敌状态"));
outtextxy(,,_T("五.只有蛇头时冲撞障碍物不死亡"));
} int second(Food & F,snake & Snake)
{
F.food=;//食物有无、蛇结束、位置、前进方向初始化
Snake.n=;
Snake.jie[].x=;
Snake.jie[].y=;
setfillcolor(RED);
fillcircle( Snake.jie[].x,Snake.jie[].y,);
Snake.dry='d';
ifstream inFile("scoremax.txt",ios::in);//读入文件
int o;
inFile>>o;
char p[];
sprintf(p, "%d", o);
settextstyle(, , _T("黑体"));
outtextxy(,,p);//最高分
sprintf(p, "%d", (Snake.n-)*);
outtextxy(,,p);//分数
return o;
} void foodstyle(Food & F,wall Wall)
{
if(!F.food)
{
F.foodxy.x=(rand()%)*+;//食物出现地点
F.foodxy.y=(rand()%)*+;
//确保食物不出现在障碍物及蛇初始位置
while((F.foodxy.x==&&F.foodxy.y==)||(F.foodxy.x==&&F.foodxy.y==))
{
F.foodxy.x=(rand()%)*+;
F.foodxy.y=(rand()%)*+;
}
for(int i=;i<Wall.n;i++)
{
if(F.foodxy.x==Wall.dry[i].x&&F.foodxy.y==Wall.dry[i].y)
{
foodstyle(F,Wall);
}
}
setlinestyle(PS_SOLID);
if((F.c+)%==&&(F.c+)!=)//判断是否为特殊食物
{
setfillcolor(GREEN);
}
else
{
setfillcolor(YELLOW);
}
fillcircle(F.foodxy.x,F.foodxy.y,);
F.food=;//食物状态为有
F.c++;//累计出现食物个数
}
}
void judge(Food & F,snake & Snake,int o,wall Wall)
{
if(Snake.jie[].x<=||Snake.jie[].x>=||Snake.jie[].y<=||Snake.jie[].y>=)
{//判断是否撞墙
PlaySound("zhuangqiang.wav",NULL,SND_FILENAME|SND_ASYNC);
Sleep();
gameover(Snake,o);
}
for(int i=;i<=Snake.n;i++)
{//判断是否咬到自己
if(Snake.jie[].x==Snake.jie[i].x&&Snake.jie[].y==Snake.jie[i].y)
{
PlaySound("yao.wav",NULL,SND_FILENAME|SND_ASYNC);
Sleep();
gameover(Snake,o);
}
}
for(i=;i<Wall.n;i++)
{//判断是否撞到障碍物
if(Snake.jie[].x<Wall.dry[i].x+&&Snake.jie[].y<Wall.dry[i].y+&&
Snake.jie[].x>Wall.dry[i].x-&&Snake.jie[].y>Wall.dry[i].y-)
{
if((F.c-)%!=&&F.c!=)//非无敌状态
{
PlaySound("zhuangqiang.wav",NULL,SND_FILENAME|SND_ASYNC);
Sleep();
gameover(Snake,o);
}
}
} } void judge2(Food & F,snake & Snake)
{
if(Snake.jie[].x==F.foodxy.x&&Snake.jie[].y==F.foodxy.y)//判断是否吃到食物
{
PlaySound("shiwu.wav",NULL,SND_FILENAME|SND_ASYNC);
setfillcolor(BLACK);//擦除
fillcircle(F.foodxy.x,F.foodxy.y,);
Snake.n++;//蛇结数增加
setfillcolor(BLUE);
fillcircle( F.foodxy.x,F.foodxy.y,);
F.food=;//食物被吃掉
}
}
void gameover(snake Snake,int o)
{
if(o<=(Snake.n-)*)//判断是否需要更改最高分
{
PlaySound("zhangsheng.wav",NULL,SND_FILENAME|SND_ASYNC);
ofstream outFile("scoremax.txt",ios::out);//写入文件
outFile<<(Snake.n-)*;
outFile.close();
}
else
{
PlaySound("Game_over.wav",NULL,SND_FILENAME|SND_ASYNC);
}
settextcolor(RED);
settextstyle(, , _T("黑体"));
outtextxy(,,_T("GAME OVER"));
settextstyle(, , _T("黑体"));
outtextxy(,,_T("是否重新开始"));
outtextxy(,,_T("YES(Y/y)"));
outtextxy(,,_T("NO(N/n)"));
char c=getch();//判断是否重新开始
if(c=='n'||c=='N')
{
closegraph();//关闭画布
}
else if(c=='y'||c=='Y')
{
main();
}
else//避免输入移动指令破坏画面
{
gameover(Snake,o);
} } void snakemove(Food & F,snake & Snake,wall Wall)
{
int i;
for (i=Snake.n ; i>; i--)//蛇身每一节移到前一节位置
{
Snake.jie[i].x = Snake.jie[i-].x;
Snake.jie[i].y = Snake.jie[i-].y;
}
switch (Snake.dry)//判断之前的移动方向 蛇头并按该方向移到
{
case 'W':
case 'w':
Snake.jie[].y-=;
break;
case 's':
case 'S':
Snake.jie[].y +=;
break;
case 'A':
case 'a':
Snake.jie[].x -=;
break;
case 'D':
case 'd':
Snake.jie[].x +=;
break;
};
snakeshow(F,Snake,Wall);//将结果显示
} void change(Food & F,snake & Snake,int o)
{
char key,p[];
IMAGE tmp;
int i;
key = getch();
switch (key)
{
case 'w':
case 'W':
if (Snake.dry !='s'&&Snake.dry !='S')//确保不反向移动
{
Snake.dry ='w';
}
break;
case 's':
case 'S':
if (Snake.dry !='w'&&Snake.dry !='W')
{
Snake.dry = 's';
}
break;
case 'a':
case 'A':
if (Snake.dry !='D'&&Snake.dry !='d')
{
Snake.dry = 'a';
}
break;
case 'd':
case 'D':
if (Snake.dry !='a'&&Snake.dry !='A')
{
Snake.dry = 'd';
}
break;
case' '://暂停 getimage(&tmp,,,,);//将该区域图像保存
settextstyle(, , _T("黑体"));
outtextxy(, , _T("任意键继续"));
PlaySound("stop.wav",NULL,SND_FILENAME|SND_ASYNC);
getch();
putimage(,,&tmp);//将保存图像返回,确保不破坏背景
for(i=;i>=;i--)//倒计时
{
settextstyle(, , _T("黑体"));
sprintf(p, "%d", i);
outtextxy(, , p);
Sleep();
putimage(,,&tmp);
}
PlaySound("start.wav",NULL,SND_FILENAME|SND_ASYNC);
break;
case :
gameover(Snake,o);//退出
break;
}
} void snakeshow(Food & F,snake & Snake,wall Wall)
{
int i;
for (i=Snake.n-; i>; i--)//蛇身
{
setfillcolor(BLUE);
fillcircle( Snake.jie[i].x,Snake.jie[i].y,);
}
if((F.c-)%==&&F.c!=)//特殊食物
{
setfillcolor(GREEN);
}
else
{
setfillcolor(RED);
}
fillcircle( Snake.jie[].x,Snake.jie[].y,);
setlinecolor(BLACK);
setfillcolor(BLACK);//擦除之前最后一节蛇身
fillcircle( Snake.jie[Snake.n].x,Snake.jie[Snake.n].y,);
if(Snake.n>)
{
setfillcolor(BLUE);
}
else
{
setfillcolor(RED);
}
fillcircle( Snake.jie[Snake.n-].x,Snake.jie[Snake.n-].y,);
} void score(snake Snake)
{
char p[];
sprintf(p, "%d", (Snake.n-)*);
settextcolor(BLACK);
outtextxy(,,p);
sprintf(p, "%d", (Snake.n-)*);
settextcolor(RED);
settextstyle(, , _T("黑体"));
outtextxy(,,p); } void wallstyle(wall & Wall)
{
Wall.n =wallnum;
for(int i=;i<Wall.n;i++)
{
Wall.dry[i].x=(rand()%)*+;//障碍物出现地点
Wall.dry[i].y=(rand()%)*+;
while((Wall.dry[i].x==&&Wall.dry[i].y==)||(Wall.dry[i].x==&&Wall.dry[i].y==)
||(Wall.dry[i].x==&&Wall.dry[i].y==))
{
Wall.dry[i].x=(rand()%)*+;//障碍物出现地点
Wall.dry[i].y=(rand()%)*+;
}
setfillcolor(RED);
fillrectangle(Wall.dry[i].x-,Wall.dry[i].y-,Wall.dry[i].x+,Wall.dry[i].y+);
for(int j=;j<i;j++)//确保障碍物不重叠
{
if(Wall.dry[i].x==Wall.dry[j].x&&Wall.dry[i].y==Wall.dry[j].y)
{
i--;
}
}
}
}
easyx图形库做贪吃蛇游戏的更多相关文章
- 基于EasyX库的贪吃蛇游戏——C语言实现
接触编程有段时间了,一直想学习怎么去写个游戏来练练手.在看了B站上的教学终于可以自己试试怎么实现贪吃蛇这个游戏了.好了,废话不多说,我们来看看如何用EasyX库来实现贪吃蛇. 一.准备 工具vc++6 ...
- Android快乐贪吃蛇游戏实战项目开发教程-01项目概述与目录
一.项目简介 贪吃蛇是一个很经典的游戏,也很适合用来学习.本教程将和大家一起做一个Android版的贪吃蛇游戏. 我已经将做好的案例上传到了应用宝,无病毒.无广告,大家可以放心下载下来把玩一下.应用宝 ...
- WebGL实现HTML5的3D贪吃蛇游戏
js1k.com收集了小于1k的javascript小例子,里面有很多很炫很酷的游戏和特效,今年规则又增加了新花样,传统的classic类型基础上又增加了WebGL类型,以及允许增加到2K的++类型, ...
- 100行JS实现HTML5的3D贪吃蛇游戏
js1k.com收集了小于1k的javascript小例子,里面有很多很炫很酷的游戏和特效,今年规则又增加了新花样,传统的classic类型基础上又增加了WebGL类型,以及允许增加到2K的++类型, ...
- 「JavaScript」手起刀落-一起来写经典的贪吃蛇游戏
回味 小时候玩的经典贪吃蛇游戏我们印象仍然深刻,谋划了几天,小时候喜欢玩的游戏,长大了终于有能力把他做出来(从来都没有通关过,不知道自己写的程序,是不是能通关了...),好了,闲话不多谈,先来看一下效 ...
- Love2D游戏引擎制作贪吃蛇游戏
代码地址如下:http://www.demodashi.com/demo/15051.html Love2D游戏引擎制作贪吃蛇游戏 内附有linux下的makefile,windows下的生成方法请查 ...
- Qt 学习之路 2(33):贪吃蛇游戏(3)
Qt 学习之路 2(33):贪吃蛇游戏(3) 豆子 2012年12月29日 Qt 学习之路 2 16条评论 继续前面一章的内容.上次我们讲完了有关蛇的静态部分,也就是绘制部分.现在,我们开始添加游戏控 ...
- Qt 学习之路 2(32):贪吃蛇游戏(2)
Qt 学习之路 2(32):贪吃蛇游戏(2) 豆子 2012年12月27日 Qt 学习之路 2 55条评论 下面我们继续上一章的内容.在上一章中,我们已经完成了地图的设计,当然是相当简单的.在我们的游 ...
- 用C++实现的贪吃蛇游戏
我是一个C++初学者,控制台实现了一个贪吃蛇游戏. 代码如下: //"贪吃蛇游戏"V1.0 //李国良于2016年12月29日编写完成 #include <iostream& ...
随机推荐
- 【[SDOI2017]数字表格】
求 \[Ans=\prod_{i=1}^N\prod_{j=1}^MFib[(i,j)]\] 连乘的反演,其实并没有什么不一样 我们把套路柿子拿出来 \[F(n)=\sum_{i=1}^N\sum_{ ...
- P3694 邦邦的大合唱站队
题目背景 BanG Dream!里的所有偶像乐队要一起大合唱,不过在排队上出了一些问题. 题目描述 N个偶像排成一列,他们来自M个不同的乐队.每个团队至少有一个偶像. 现在要求重新安排队列,使来自同一 ...
- WebForm下的$.ajax中contentType: “application/json” 的用法
不使用contentType: “application/json”则data可以是对象 $.ajax({ url: actionurl, type: "POST", datTyp ...
- ASP.NET web api 跨域请求
1.学习文章:AJAX 跨域请求 - JSONP获取JSON数据 1.asp.net代码 参考文章:http://www.sxt.cn/info-2790-u-756.html (1).增加CorsH ...
- 在Windows10中更改”WIN+E“快捷键打开目标
1> 复制下面代码到记事本保存为launch.vbs 2> 然后打开Regedit.exe并创建以下注册表分支 HKCU:\Software\Classes\CLSID\{52205fd8 ...
- Python:基础知识(二)
常用模块 urllib2 :用于发送网络请求,获取数据 (Pyhton2中的urllib2工具包,在Python3中分拆成了urllib.request和urllib.error两个包.) json: ...
- 动态验证码处理UI自动化获取处理
解决思路两种:1.直接linux catalina.out读取:一分每10s轮询出现新的直接读取返回<br>2.缓存注入cookie,先手动登录获取session 然后通过注入user,p ...
- NYOJ 252 01串 普通dp
题目链接: http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=252 分析: dp[2][0]=2;//表示长度为2的满足要求的且以0结尾的串个数 ...
- 轻量级IOC容器:Ninject
Ninject是一个快如闪电.超轻量级的基于.Net平台的依赖注入框架.它能够帮助你把应用程序分离成一个个松耦合.高内聚的模块,然后用一种灵活的方式组装起来.通过使用Ninject配套你的软件架构,那 ...
- 【OC底层】Category、+load方法、+initialize方法原理
Category原理 - Category编译之后的底层结构是 struct categroy_t,里面存储着分类对象方法.属性.协议信息- 当程序运行时,通过runtime动态的将分类的方法.属性. ...