C语言贪吃蛇详解4,c语言贪吃蛇详解4.食物的投放与蛇的变长
c语言贪吃蛇详解4.食物的投放与蛇的变长
前几天的实验室培训课后作业我布置了贪吃蛇,今天有时间就来写一下题解。我将分几步来教大家写一个贪吃蛇小游戏。由于大家c语言未学完,这个教程只涉及数组和函数等知识点。
通过前几次的教程,我们已经做出来了能上下左右跑的小蛇了。现在我们就先来做下食物投放吧。
食物投放的基本思想是在地图上随机找一个没有蛇身也没有障碍物的地方,然后把这个地方的地图数组值标记为-1(前面我们让空地为0,障碍物为1)。
我们先来写一个函数来判断一个点是不是符合上面的条件。
int check(int ii,int jj) //判断这个点能不能放食物,可以放返回1,不能放返回0
{if(a[ii][jj]==1) //如果有障碍物,返回0
return 0;inti;for(i=0; i
{if(ii==s[i]0&&jj==s[i][1]) //如果和其中一个蛇身重合,就返回0
return 0;
}if(ii==0||ii==H-1||jj==0||jj==W-1) //如果在边界上面,返回0
return 0;return 1; //最后筛选 过后的是符合条件的点
}
要使用随机数,先
#include
然后由于要根据时间设置随机数种子,所以要
#include
在init函数里面写这句代码
srand((unsigned)time(NULL)); //设置随机数种子为现在的时间
然后写一个food函数,实现投放一个食物
voidfood()
{inti,j;do{
i=rand()%H; //生成0~H-1之间的一个数
j=rand()%W;
}while(check(i,j)==0); //生成点直到满足条件
a[i][j]=-1; //标记为食物
gotoxy(i,j);
printf("$"); //画出食物
}
然后在main里面的循环前面调用一次food,实现开始游戏时有一个食物。然后检查蛇头与食物是否重合,如果重合,就调用一次food,投放一个食物。
intmain()
{
init();//程序开始时的初始化操作
drawMap(); //画地图
food();while(1)
{
drawSnake();//画蛇
Sleep(WAIT_TIME); //等待一段时间
key();
move();//移动蛇(主要是修改蛇身数组的数据)
if(a[s[0][0]][s[0][1]]==-1) //如果蛇头碰到食物,就重新投放食物,并且把食物点重置为0
{
food();
a[s[0][0]][s[0][1]]=0;
}
}
getchar();return 0;
}
让我们来看看效果
到现在为止的代码:
#include #include#include#include#include
#define H 23
#define W 75
#define WAIT_TIME 500
//定义direction的每个值代表的方向
#define UP 0
#define DOWN 1
#define LEFT 2
#define RIGHT 3
int a[H][W]; //地图数组
int s[H*W][2]; //蛇身坐标数组
int sLength; //蛇的长度
int direction; //蛇的方向
void init() //程序开始时的初始化操作
{
srand((unsigned)time(NULL));//设置随机数种子为现在的时间
CONSOLE_CURSOR_INFO cursor_info = {1, 0};
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info); //隐藏关标
inti,j;for(i=0; i
{
a[i][0]=1; //让第一列为1
a[i][W-1]=1; //让最后一列为1
}for(j=0; j
{
a[0][j]=1; //让第一行为1
a[H-1][j]=1; //让最后一行为1
}
sLength=4; //让蛇的最初长度为4
s[0][0]=H/2;
s[0][1]=W/2; //给蛇头坐标赋值
for(i=1; i<4; i++)
{
s[i][0]=s[0][0]+i;
s[i][1]=s[0][1]; //给刚开始的蛇身几个初始坐标
}
direction=UP;
}void gotoxy(int i,int j) //移动光标
{
COORD position={j,i};
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),position);
}int check(int ii,int jj) //判断这个点能不能放食物,可以放返回1,不能放返回0
{if(a[ii][jj]==1) //如果有障碍物,返回0
return 0;inti;for(i=0; i
{if(ii==s[i][0]&&jj==s[i][1]) //如果和其中一个蛇身重合,就返回0
return 0;
}if(ii==0||ii==H-1||jj==0||jj==W-1) //如果在边界上面,返回0
return 0;return 1; //最后筛选 过后的是符合条件的点
}voidfood()
{inti,j;do{
i=rand()%H; //生成0~H-1之间的一个数
j=rand()%W;
}while(check(i,j)==0); //生成点直到满足条件
a[i][j]=-1; //标记为食物
gotoxy(i,j);
printf("$"); //画出食物
}void drawMap() //画地图
{
gotoxy(0,0);inti,j;for(i=0; i
{for(j=0; j
{if(a[i][j]==0) //为0输出空格
printf(" ");else //为1输出#
printf("#");
}
printf("\n"); //别忘了换行
}
}voidmove()
{inti;
gotoxy(s[sLength-1][0],s[sLength-1][1]);
printf(" "); //在尾巴上面画空格以擦除尾巴
for(i=sLength-1; i>0; i--) //从尾巴开始,每一个点的位置等于它前面一个点的位置
{
s[i][0]=s[i-1][0];
s[i][1]=s[i-1][1];
}switch(direction)
{caseUP:
s[0][0]--;break;caseDOWN:
s[0][0]++;break;caseLEFT:
s[0][1]--;break;caseRIGHT:
s[0][1]++;break;
}
}void drawSnake() //画蛇
{inti;for(i=0; i
{
gotoxy(s[i][0],s[i][1]); //移动关标到蛇的坐标
printf("@"); //在这个位置画蛇
}
}voidkey()
{if(kbhit()!=0) //如果有键盘输入
{char in;while(!kbhit()==0) //如果玩家输入了多个按键,以最后一个按键为准
in=getch();switch(in)
{case 'w':case 'W':if(direction!=DOWN) //不能缩头吧。。。。
direction=UP;break;case 's':case 'S':if(direction!=UP)
direction=DOWN;break;case 'a':case 'A':if(direction!=RIGHT)
direction=LEFT;break;case 'd':case 'D':if(direction!=LEFT)
direction=RIGHT;break;
}
}
}intmain()
{
init();//程序开始时的初始化操作
drawMap(); //画地图
food();while(1)
{
drawSnake();//画蛇
Sleep(WAIT_TIME); //等待一段时间
key();
move();//移动蛇(主要是修改蛇身数组的数据)
if(a[s[0][0]][s[0][1]]==-1) //如果蛇头碰到食物,就重新投放食物,并且把食物点重置为0
{
food();
a[s[0][0]][s[0][1]]=0;
}
}
getchar();return 0;
}
好了,现在食物能正常投放了
接下来我们就来实现一下蛇吃到食物的变长功能吧。
首先设置一个变量标记蛇是否吃到食物
bool eated=false; //标记是否吃到食物
然后在main里面的判断吃到食物时,使eated变为true
if(a[s[0][0]][s[0][1]]==-1) //如果蛇头碰到食物,就重新投放食物,并且把食物点重置为0
{
eated=true; //标记已经吃到食物
food();
a[s[0][0]][s[0][1]]=0; //去掉食物
}
然后在move函数里面加下面的代码
if(eated) //如果吃到了食物
{
sLength++;
eated=false; //设置为false,不然无限变长
}
这样在下面的坐标移动环节,就不会舍弃掉上一次的尾巴节点。蛇就变长了。
来看看效果:
蛇可以变长了。不过有时候玩着玩着有事,又舍不得玩了这么长的蛇,要是有个暂停功能就好了。接下来我们就来顺便实现下。
在key函数里面的switch里面加一个case
case 'p':case 'P':
gotoxy(H,0); //将光标移动到下面
system("pause");
gotoxy(H,0);
printf(" "); //消去下面的按任意键继续
break;
这样就可以实现按p键暂停了。(记得玩的时候切换为英文输入法呀)
来看看到现在为止的代码:
#include #include#include#include#include
#define H 23
#define W 75
#define WAIT_TIME 500
//定义direction的每个值代表的方向
#define UP 0
#define DOWN 1
#define LEFT 2
#define RIGHT 3
int a[H][W]; //地图数组
int s[H*W][2]; //蛇身坐标数组
int sLength; //蛇的长度
int direction; //蛇的方向
bool eated=false; //标记是否吃到食物
void init() //程序开始时的初始化操作
{
srand((unsigned)time(NULL));//设置随机数种子为现在的时间
CONSOLE_CURSOR_INFO cursor_info = {1, 0};
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info); //隐藏关标
inti,j;for(i=0; i
{
a[i][0]=1; //让第一列为1
a[i][W-1]=1; //让最后一列为1
}for(j=0; j
{
a[0][j]=1; //让第一行为1
a[H-1][j]=1; //让最后一行为1
}
sLength=4; //让蛇的最初长度为4
s[0][0]=H/2;
s[0][1]=W/2; //给蛇头坐标赋值
for(i=1; i<4; i++)
{
s[i][0]=s[0][0]+i;
s[i][1]=s[0][1]; //给刚开始的蛇身几个初始坐标
}
direction=UP;
}void gotoxy(int i,int j) //移动光标
{
COORD position={j,i};
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),position);
}int check(int ii,int jj) //判断这个点能不能放食物,可以放返回1,不能放返回0
{if(a[ii][jj]==1) //如果有障碍物,返回0
return 0;inti;for(i=0; i
{if(ii==s[i][0]&&jj==s[i][1]) //如果和其中一个蛇身重合,就返回0
return 0;
}if(ii==0||ii==H-1||jj==0||jj==W-1) //如果在边界上面,返回0
return 0;return 1; //最后筛选 过后的是符合条件的点
}voidfood()
{inti,j;do{
i=rand()%H; //生成0~H-1之间的一个数
j=rand()%W;
}while(check(i,j)==0); //生成点直到满足条件
a[i][j]=-1; //标记为食物
gotoxy(i,j);
printf("$"); //画出食物
}void drawMap() //画地图
{
gotoxy(0,0);inti,j;for(i=0; i
{for(j=0; j
{if(a[i][j]==0) //为0输出空格
printf(" ");else //为1输出#
printf("#");
}
printf("\n"); //别忘了换行
}
}voidmove()
{inti;
gotoxy(s[sLength-1][0],s[sLength-1][1]);
printf(" "); //在尾巴上面画空格以擦除尾巴
if(eated) //如果吃到了食物
{
sLength++;
eated=false; //设置为false,不然无限变长
}for(i=sLength-1; i>0; i--) //从尾巴开始,每一个点的位置等于它前面一个点的位置
{
s[i][0]=s[i-1][0];
s[i][1]=s[i-1][1];
}switch(direction)
{caseUP:
s[0][0]--;break;caseDOWN:
s[0][0]++;break;caseLEFT:
s[0][1]--;break;caseRIGHT:
s[0][1]++;break;
}
}void drawSnake() //画蛇
{inti;for(i=0; i
{
gotoxy(s[i][0],s[i][1]); //移动关标到蛇的坐标
printf("@"); //在这个位置画蛇
}
}voidkey()
{if(kbhit()!=0) //如果有键盘输入
{char in;while(!kbhit()==0) //如果玩家输入了多个按键,以最后一个按键为准
in=getch();switch(in)
{case 'w':case 'W':if(direction!=DOWN) //不能缩头吧。。。。
direction=UP;break;case 's':case 'S':if(direction!=UP)
direction=DOWN;break;case 'a':case 'A':if(direction!=RIGHT)
direction=LEFT;break;case 'd':case 'D':if(direction!=LEFT)
direction=RIGHT;break;case 'p':case 'P':
gotoxy(H,0); //将光标移动到下面
system("pause");
gotoxy(H,0);
printf(" "); //消去下面的按任意键继续
break;
}
}
}intmain()
{
init();//程序开始时的初始化操作
drawMap(); //画地图
food();while(1)
{
drawSnake();//画蛇
Sleep(WAIT_TIME); //等待一段时间
key();
move();//移动蛇(主要是修改蛇身数组的数据)
if(a[s[0][0]][s[0][1]]==-1) //如果蛇头碰到食物,就重新投放食物,并且把食物点重置为0
{
eated=true; //标记已经吃到食物
food();
a[s[0][0]][s[0][1]]=0; //去掉食物
}
}
getchar();return 0;
}
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
C语言贪吃蛇详解4,c语言贪吃蛇详解4.食物的投放与蛇的变长相关推荐
- C语言处理贪吃蛇游戏蛇的长度,c语言贪吃蛇详解4.食物的投放与蛇的变长
c语言贪吃蛇详解4.食物的投放与蛇的变长 前几天的实验室培训课后作业我布置了贪吃蛇,今天有时间就来写一下题解.我将分几步来教大家写一个贪吃蛇小游戏.由于大家c语言未学完,这个教程只涉及数组和函数等知识 ...
- C语言分支与循环--分支篇,那些分支语句的坑你都避开了吗(附加C99变长数组)
前言
- 汇编语言贪吃蛇、俄罗斯方块双任务设计实现详解(二)——贪吃蛇详细设计
详细设计: 2.贪吃蛇详细设计: 如下图所示左下角为主程序对贪吃蛇相关子程序的调用,程序中init_left_window子程序功能为将左侧窗口非边框部分置为空.左边上侧和右侧是贪吃蛇段中,贪吃蛇程序 ...
- 嵌入式c语言为什么变量定义在前面,嵌入式C语言数据类型和变量详解
原标题:嵌入式C语言数据类型和变量详解 一般来讲,标准的C语言类型在嵌入式编译器中是合法的.但由于嵌入式控制器的受限环境.嵌入式c语言的变量和数据类型具有新的特征,这些特征体现在如下方面. 嵌入式C语 ...
- c++贪吃蛇_细致的C语言写贪吃蛇教程+详细思路-适合新手附源码
在有用C写贪吃蛇的一个想法之后,上网查了几个教程,觉得不是很能看懂.恩...或者说不是一下子就能看出来思路+具体怎么实现.所以,我花了早自习的时间想了想如何用最简单的方法实现,晚上大约两个小时写了出来 ...
- c语言path环境变量,Windows下PATH等环境变量详解(转载)
在学习JAVA的过程中,涉及到多个环境变量(environment variable)的概念,如PATH.正确地配置这些环境变量,是能够顺利学习.开发的前提.而经常出现的问题是:有的学习者能够按照提示 ...
- C语言指针详解——入门C语言指针,初级指针使用。
原文地址:我的个人博客点击查看 C语言教程第二弹--指针详解 所有学过C语言的人都知道,C语言难在它的指针的使用和理解,今天,我带给大家C语言的指针的教程,供大家学习交流,如果有讲的不对的地方,请给作 ...
- c语言写程序if else,if else用法详解,C语言if else用法完全攻略
if else 语句是一种选择结构,可以让代码选择执行.所谓选择执行,就是"某些代码可能执行,也可能不执行,有选择地执行某些代码". if 的最简单用法 if最简单的格式是: if ...
- c语言:数据保存的方法实现简易贪吃蛇
贪吃蛇作为我童年第一个接触的手机游戏,在学c语言的时候就一直在想什么时候可以自己实现.经过一年的学习也是终于写出来了,在这期间我看了很多其它博客上的文章,我也很感谢那些愿意把自己的知识在网上和大家分享 ...
最新文章
- Python代码编写过程中有哪些重要技巧?
- 盘点那些最常用的Linux命令,都应该记熟!
- 《Spring 5 官方文档》18. Web MVC 框架(五)
- UE4蓝图中的AI行为树功能使用经验指南
- python 归并排序,合并有序数组,逆序对个数
- 七十六、SpringBoot 的数据缓存cache+Redis(三)
- dg oracle 切换模式_oracle dg切换操作示例
- ftp模式 503、227错误
- 使用扩展技术将SAP Fiori应用隐藏动态创建的UI字段
- 美团点评金融平台Web前端技术体系
- php中将SimpleXMLElement Object数组转化为普通数组
- 批量实现 cv2.cvtColor(images, cv2.COLOR_GRAY2RGB)
- Java二分查找法代码
- 【使用教程】面向回家编程-12306智能刷票,订票
- rk3568 android 11 更换系统签名
- csrss.exe和winlogon.exe引起cpu居高不下的解决办法
- 浏览器主页被更改成7654主页
- Ubuntu挂载ISO文件
- Pop3得到的Email 信件格式介绍
- Stata实现结构方程模型
热门文章
- MindManager2020英文界面切换中文界面教程
- 猿创征文 | 一文看懂!无人机集群半物理仿真系统的7大模块拆解,超详细!
- linux下性能监控工具Nmon的使用以及通过nmon_analyse生成分析报表
- 谷歌今年或发布两款大屏智能手机
- oracle性能调优总结,Oracle的调优方法总结
- 当哪种公司做什么性质的销售才能够拿到高工资的探讨
- Linux下数据库连接超时时长,关于.Net Core 部署在Linux下连接SqlServer数据库超时解决办法...
- 代理模式(四):代理模式效果与适用场景
- 关于-fPIC, -fPIE的一点理解
- JPEG压缩算法的Python实现 -- 2 JPEG介绍