文章目录

前言

一、实现原理

1、地图打印

2、蛇身运动

3、方向键操控

4、四种判定

5、函数工具

二、游戏试玩

1、编译环境

2、源代码

三、代码详解

1、游戏配置部分(第1~31行)

2、游戏主体部分(第32~80行)

3、游戏结束部分(第81~99行)

结语

前言

学完C语言但不会写贪吃蛇?

嗯嗯没毛病,书上的C语言其给人的感觉也就是用来输出设计好的文字和图像,或者拿来解决数学问题,一顿操作之后输出函数静静地在屏幕上输出结果。而这些都是静态的输出,但游戏应该是动态的输出。

所以要编写贪吃蛇,首先要解决的就是如何输出动态图像的问题。

一、实现原理

二维数组和链表?并没有用到,连开始用的结构体都在后期优化当中用两个一维数组代替了。

1、地图打印

二维数组存放地图打印刷新烦人,地图越大越晃眼。这里采用坐标函数配合printf()函数来打印地图,并且打印蛇身和食物也是用这个方法。

使用坐标函数需要调用头文件windows.h,然后自定义这个函数,名字叫什么都可以,这里沿用gotoxy()。其作用很简单,就是将光标移动到指定的坐标。

void gotoxy(int x,int y)

{

COORD p;

p.X=x,p.Y=y;

SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),p);

}

gotoxy()的详细函数说明看这里。

两个for循环加gotoxy()就可轻松打印出方形地图,并且只需打印一次,不像二维数组一样要重复刷新。

注意我编写代码用的是汉字作为输出图形,一个汉字占两个字符位置,从设计的坐标位置到打印坐标位置横坐标要乘以2。

2、蛇身运动

只需用坐标打印新蛇头并删除蛇尾就能完成一次移动,随后让蛇身的后一节坐标依次等于前一节坐标,完成下次移动的准备。

整个蛇身的移动由循环函数实现,以Sleep()函数暂停以实现速度控制,而不是瞬间完成循环。

3、方向键操控

由kbhit()、getch()和switch()函数完成实现:敲击方向键,退出当前方向运动循环,重新进入键入方向对应的运动循环。

4、四种判定

撞墙判定:由蛇头部和墙坐标重合触发,退出运动循环进而选择重新开始或退出游戏。

自食判定:由蛇头部和蛇身坐标重合触发,退出运动循环进而选择重新开始或退出游戏。

增长判定:由蛇头部和食物坐标重合触发,然后蛇身增长,食物重新刷新。

通关判定:由蛇总体长度达到设定长度触发,退出运动循环进而选择下一难度或退出游戏。

5、函数工具

gotoxy()、srand()、rand()、Sleep()、kbhit()、getch(),system(),整个实现游戏的代码需要用到以上7个函数,其他的就只是for()、while()、if()、switch()等基本函数了。

其中srand()函数和rand()函数仅用于食物的随机刷新,srand()函数仅出现1次,rand()函数出现于2处。

kbhit()函数和getch()函数用于键盘方向键操作和游戏结束时的选择,kbhit()函数出现3次,getch()函数出现2次。

Sleep()函数仅出现1次。

system(“cls”)用于重启游戏时刷屏,仅出现1次。

这7个函数的讲解可查看我的其他博文,或自行搜索。

二、游戏试玩

1、编译环境

编码选择:建议选择GB18030,否则游戏中的汉字可能出现乱码。或者也可以选择把代码中的汉字重打一遍。

游戏源代码编译通用性检测:用了一新一老编译器测试,通用性良好,毕竟vc++6.0都能编译通过。

2、源代码

#include

#include

#include

#include

#include

int I=13,J=16,L=6,level=1,_speed=700;

void gotoxy(int x,int y){

COORD p;

p.X=x,p.Y=y;

SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),p);

}

int main()

{

res:int x[100],y[100],xo,yo,choose=2,length=3,fact=0,ability=0;

x[1]=3,y[1]=6,x[2]=2,y[2]=6,x[3]=1,y[3]=6;

for(int i=0;i

gotoxy(0,i);

printf("田");

gotoxy(2*(J-1),i);

printf("田");

}

for(int j=0;j

gotoxy(2*j,0);

printf("田");

gotoxy(2*j,I-1);

printf("田");

}

srand((unsigned) time(0));

xo=rand()%(J-2)+1,yo=rand()%(I-2)+1;

gotoxy(2*xo,yo);

printf("虫");

while(1){

if(kbhit())

switch(getch()){

case 75:choose=1;break;

case 77:choose=2;break;

case 72:choose=3;break;

case 80:choose=4;

}

while(1){

switch(choose){

case 1:x[0]=x[1]-1,y[0]=y[1];break;

case 2:x[0]=x[1]+1,y[0]=y[1];break;

case 3:y[0]=y[1]-1,x[0]=x[1];break;

case 4:y[0]=y[1]+1,x[0]=x[1];

}

if(kbhit())break;

if(x[0]==xo && y[0]==yo){

xo=rand()%(J-2)+1,yo=rand()%(I-2)+1;

length++;

gotoxy(34,0);

printf("难度等级:%2d 进度得分:%3d",level,100*(length-3)/(L-3));

}

else{

gotoxy(2*x[length],y[length]);

printf(" ");

}

gotoxy(2*x[0],y[0]);

printf("口");

if(length==L)break;

for(int k=2;k<=length;k++)

if(x[0]==x[k] && y[0]==y[k])fact=1;

if(fact)break;

gotoxy(2*xo,yo);

printf("虫");

gotoxy(30,20);

Sleep(_speed);

for(int i=length;i>1;i--)x[i]=x[i-1],y[i]=y[i-1];

switch(choose){

case 1:x[1]--;break;

case 2:x[1]++;break;

case 3:y[1]--;break;

case 4:y[1]++;

}

if(x[1]<1||x[1]>J-2||y[1]<1||y[1]>I-2) break;

}

if(x[1]<1||x[1]>J-2||y[1]<1||y[1]>I-2) break;

if(fact)break;

if(length==L)break;

}

if(length==L){

gotoxy(11,14);

printf("恭喜通关!");

ability=1,level++;

printf("\n输入1进入下一难度,输入2退出游戏:");

}

else{

gotoxy(11,14);

printf("GAME OVER!");

printf("\n输入1重启游戏,输入2退出游戏:");

}

sty:while(1)if(kbhit())break;

switch(getch()){

case 49:if(ability==1)_speed=0.6*_speed,L=L/0.6;system("cls");goto res;

case 50:break;

default:goto sty;

}

return 0;

}

游戏截图:

三、代码详解

1、游戏配置部分(第1~31行)

第6行:int I=13,J=16,L=6,level=1,_speed=700;声明全局变量:

I和J是设定地图的宽和长;

L是通关长度;

level是难度等级;

_speed是Sleep()函数的参数,初始设定700毫秒。

第7~11行:定义坐标函数gotoxy(),因为全程要用到,所以定义在了主函数之前,还能省一行声明,默默地给机智的自己点一个赞。

第14行:res:int x[100],y[100],xo,yo,choose=2,length=3,fact=0,ability=0;声明变量:x[100]和y[100]是存放蛇身坐标的数组;

xo和yo是食物的坐标;

choose是选择运动方向的辅助变量,设定值为2表示开始时自动向右行进;

length是初始蛇长;

fact是辅助自食判定的变量;

ability是辅助判定是否提升难度的变量;

res:配合goto语句重启游戏。

第15行:初始化前三节蛇身坐标。

第16~27行:打印地图。

第28~31行:打印第一次的食物。

2、游戏主体部分(第32~80行)

第32行和第40行的while(1)构成嵌套循环游戏主体。

第33~39行:敲击键盘就进行方向选择,不敲击就跳过。75、77、72、80是左右上下的双ASCII码之一。

第41~46行:对应运动方向,把新蛇头坐标赋值给x[0]和y[0],如当choose=1时,x[0]=x[1]-1,y[0]=y[1];x[1]-1和y[1]就是新蛇头坐标,也就是向左移动了一格。

第47行:if(kbhit())break;检测到有键盘输入则中断循环回到上一循环,没有就跳过。

第48~57行:检测新蛇头是否吃到食物:

吃到就重新随机食物坐标,蛇身长度变量加1,得分增加,蛇尾不删除;

没吃到就去蛇尾坐标位置把蛇尾删掉。

第58~59行:打印新蛇头。

第60行:if(length==L)break;通关判定:

长度达标则跳出循环,配合第79行的相同判定跳出双嵌套循环进入游戏结束阶段;

没达标就过。

第61~63行:自食判定:

新蛇头坐标和蛇身坐标重合则跳出循环,配合第78行if(fact)break;再次判定跳出双嵌套循环进入游戏结束阶段;

没自食就过。

第64~66行:打印食物,移开光标。

第67行:Sleep(_speed);速度控制。

第68行:for(int i=length;i>1;i--)x[i]=x[i-1],y[i]=y[i-1];蛇身各坐标顺序向前一格。(仅赋值,下一循环才打印)

第69~74行:单独移动蛇头坐标,之前x[0]和y[0]是提前用了新蛇头坐标,在这里才将x[1]或y[1]移动,放在最后是因为第68行的蛇身赋值要求蛇头坐标最后改变。

第75行:if(x[1]<1||x[1]>J-2||y[1]<1||y[1]>I-2) break;撞墙判定:

撞了就跳出循环,配合第77行的相同判定跳出双嵌套循环进入游戏结束阶段;

没撞就过;

3、游戏结束部分(第81~99行)

第81~91行:判断游戏通关还是游戏失败:

长度达标则输出“恭喜通关”和选择重来或退出的提示,ability赋值为1,等级提升;

长度未达标跳出主体循环就是游戏失败了,输出“GAME OVER”和选择重来或退出的提示。

第92~97行:while(1)等待,有键盘输入则跳出并继续。49和50是1和2的ASCII码。选1进入下一难度,速度加快,通关长度要求增加,清屏回到初始代码位置,选2退出;其他键不处理,重新等待。

结语

要是超过100个赞我就考虑再写推箱子好还是俄罗斯方块好。

整个代码还有2行是不必要的,有兴趣的可以找找看。

99行不用指针 c语言贪食蛇,小白99行C代码编写经典游戏贪吃蛇(多关版本)相关推荐

  1. 99行不用指针 c语言贪食蛇,关于C语言指针的问题

    #include"iostream.h" struct student { long num; int score; student *next; }; student *crea ...

  2. 【从入门到入土系列】C语言制作小游戏-贪吃蛇:Copy+运行即可另附注释

    系列文章 本系列持续更新中,欢迎您的访问! 系列简介 本系列由唐文疏撰写,负责记录博主的学习生涯中的一点一滴.独乐乐不如众乐乐,故此分享给大家.欢迎大家一起讨论.学习和批评指点. 博主只是一个普普通通 ...

  3. Python命令行小游戏—贪吃蛇

    Python命令行小游戏-贪吃蛇 前言 一.贪吃蛇游戏初始界面及地图 1.游戏初始界面 2.游戏地图 二.命令符的设置.输出刷新和按键检测 1.库支持 2.c语言代码 3.Python代码(变量初始化 ...

  4. python vector_50行Python代码实现经典游戏,不仅是划水神器,更是学习利器!

    Free Python Games非常适合学生,它不仅具有高度的组织性和灵活性,而且能够激发人们探索和理解能力.--Terri Furton Free Python Games在轻松的环境中把游戏和学 ...

  5. python程序源码百行_百行python代码,轻松完成贪吃蛇小游戏

    引言 作为python 小白,总是觉得自己要做好百分之二百的准备,才能开始写程序.以至于常常整天在那看各种语法教程,学了几个月还是只会print('hello world'). 这样做效率太低,正确的 ...

  6. 游戏贪吃蛇(c语言)

    游戏贪吃蛇(c语言) 一.项目背景 二.设计目的 三.项目功能需求 1.初始化游戏 2.控制蛇的运行轨迹 3.控制蛇的长度 4.控制食物生成 5.计算分数 6.结束条件 四.系统的功能结构图 五.总体 ...

  7. C语言贪食蛇(数组实现)

    源码如下: #include<stdio.h> #include<windows.h> #include<time.h> #include<stdlib.h& ...

  8. 用200行C语言代码写出一个贪吃蛇——1.0(基本版)

    1.设计思路 总的来说,贪吃蛇这个小游戏涉及到的东西不多,但是对逻辑思维是比较吃基本功的. 贪吃蛇,显示给我们看的有三部分:蛇.食物.地图边界. 我们可以用一个二维数组来标记这些部分: 例如这里我创建 ...

  9. bat贪吃蛇游戏代码_100行python代码,轻松完成贪吃蛇小游戏

    来源:DataGo数据狗   链接: https://mp.weixin.qq.com/s/fDcr1SfcbynLzHye7Q7VOg 大家小时候都玩过贪吃蛇吧?小编小时候可喜欢拿爸妈的手机玩了,厉 ...

最新文章

  1. Spring 利用FactoryBean来配置Bean
  2. php word转pdf linux,Linux平台中使用PHP把word转pdf的实现方法
  3. OpenCV霍夫直线检测的实例(附完整代码)
  4. HDU1850(Nim游戏)
  5. Android UI 常用图标尺寸规范
  6. 控件 qml_Flat风格的Qml进度条
  7. Python的threadpool模块
  8. win7装oracle 11g 问题
  9. html+input改变图标,JS Input里添加小图标的两种方法
  10. docker安装mysql并配置文件_Docker安装mysql,并自定义my.cnf
  11. 自燃的特斯拉,渐失“民心”的电动车
  12. 组内相关系数intraclass correlation(ICC)
  13. 怎么看服务器硬盘是机械还是固态,怎么辨别机械硬盘和固态硬盘?(附多种方法)...
  14. 人脸识别原理:(初级篇)内含PPT
  15. Linux-CPU篇
  16. oracle 恢复用户表空间,Oracle以TSPITR方式恢复表空间数据一例
  17. 算法 + 算法 = 新算法
  18. (转)业务知识_电子商务知识
  19. python pyqtgraph绘图库-绘制图形
  20. 【Linux】Linux编程基础(vi、gcc、gdb)

热门文章

  1. 百度 2021 Lic 机器阅读理解比赛有感
  2. VUE新坑 中文乱码
  3. 安全事件日志事件编号与描述
  4. rust石头壁炉_《腐蚀》RUST生存攻略心得
  5. H5 canvas基础入门到捕鱼达人小游戏实现(1)
  6. OpenCV3 5.3 用形态学滤波器开启和闭合图像
  7. mac mysql版本_mac mysql安装哪个版本
  8. 我的一加5刷机基本步骤
  9. 我们终将泄露的人脸数据,后果到底有多可怕?
  10. 线程通信,生产者消费者问题案例,模拟来电提醒和接听电话