教你如何用C语言做一个简单的贪吃蛇

article/2025/10/26 8:42:19

小时候大家可能都玩过贪吃蛇,但有没有想过自己做一个出来玩玩看。今天我们就教大家用C语言做一个简单的贪吃蛇游戏。这里没有采用图形界面去做,而是采用win32控制台。
首先,先把做好的游戏初始界面和游戏截图先展示一下。
游戏初始界面如图:
在这里插入图片描述
在这里插入图片描述
游戏截图如图所示:
在这里插入图片描述
第一步
我们要搭建一个游戏的初始界面。这里我们直接采用printf()函数将界面直接打出来,然后用getch()函数来获取键盘输入的字符并将其赋值给ch1再判断ch1是否等于j,如果是则调用system(“cls”)函数清屏,然后就进入设置炸弹数量的界面,然后再用getch()函数获取输入的字符并赋值给ch2,然后再根据ch2的值来使相应标志位置1(这里的标志位是决定后面的炸弹数)。

//初始界面 
int show(){char ch1,ch2;printf("                   |----------------------------------------------------------------------------------|\n");    //欢迎界面 printf("                   |                                                                                  |\n");printf("                   |                                                                                  |\n");printf("                   |                            欢迎来到贪吃蛇小游戏                                  |\n");printf("                   |游戏规则:1.通过awsd来进行上下左右控制贪吃蛇,按k来增加速度,按L使速度初始化        |\n");printf("                   |          2.贪吃蛇吃到炸弹则生命值减1,吃到一个食物则分数加1,吃到自己生命值减1     |\n"); printf("                   |          4.如果往蛇自己的现态反方向运动,则吃到一个身位减一个生命值              |\n");printf("                   |          4.字母Q代表炸弹,字母$代表食物                                          |\n"); printf("                   |          5.生命值为0则游戏结束                                                   |\n");printf("                   |          6.按'j'来开始游戏                                                       |\n");printf("                   |                                                                                  |\n");printf("                   |----------------------------------------------------------------------------------|\n");ch1=getch();if(ch1=='j'){system("cls");      //清空函数 ks=1;}printf("               !! 请选择几个炸弹,输入2则出现两个炸弹,输入3则出现三个炸弹,默认为一个炸弹!!           \n"); ch2=getch();if(ch2=='2'){ system("cls");zd1=1;}if(ch2=='3'){ system("cls");  zd2=1;}else  system("cls");            //如果按下其他的键则默认一个炸弹 return ks;
} 

第二步,我们创建好了初始界面后,我们就需要做一个简易的游戏地图,因为你玩贪吃蛇嘛,总要给它设置一个范围吧,当然你也可以设置整个窗口都是地图,这个等我们讲完地图如何设置,你自己可以来决定地图的范围。
这里我们先定义它的范围,后期相关物体的位置都是根据它的范围来的。

#define High 20         //设置范围 
#define Width 40

下面这代码是给墙设置一个标志位,因为我们这里使采用标志位来区分开墙,蛇头,蛇身,炸弹,食物。然后我们再用动态扫描的方法把地图都扫描一遍,根据不同的标志位来打印不同的字符,这样就可以实现一个完整的游戏。这里我们先讲解怎么打印墙,也就是贪吃蛇的活动范围。
下面这段代码的含义是将第一行和最后一行以及第一列和最后一列的标志位为-1。

	for(i=0;i<High;i++){map[i][0]=-1;               //每一行的第一个赋值为-1 map[i][Width-1]=-1;         //每一行的最后一个赋值为-1 }for(j=0;j<Width;j++){ map[0][j]=-1;              //第一行全为-1 map[High-1][j]=-1;         //最后一行全为-1 }

然后这里我们通过扫描整个范围的地图,依次根据不同的标志位值来打印不同的物体,当标志位为-1时候就打印出#,我们可以从游戏截图的图片里面看出我们打印的城墙效果。

	for(i=0;i<High;i++){for(j=0;j<Width;j++){if(map[i][j]==-1) printf("#");                        //输出城墙 else if(map[i][j]==-2)  printf("$");                 //输出食物 else if(map[i][j]==0)   printf(" ");                 //输出空格 else if(map[i][j]>1)    printf("*");                 //输出蛇身 else if(map[i][j]==1)   printf("@");                //输出蛇头else if(map[i][j]<=-3)  printf("Q");               //输出炸弹 }printf("\n");}

第三步,我们来显示贪吃蛇,首先蛇的话我们分蛇头和蛇身。
这里我们将蛇头的标志位置1。然后用@来表示蛇头,下面map[High/2][Width/2-k]=k+1则是定义蛇尾的表示为5。

	//设计蛇头的元素组为1map[High/2][Width/2]=1;       //设置蛇头位置的标志位  for(k=1;k<5;k++){map[High/2][Width/2-k]=k+1;       //设置蛇尾的标志位 }

我们从这里可以看出蛇头的标志位为1,然后大于1的都为蛇身

       else if(map[i][j]>1)    printf("*");                 //输出蛇身 else if(map[i][j]==1)   printf("@");                //输出蛇头

然后我们要让蛇动起来的话我们要设置蛇的运动方向和蛇的移动。
这里我们通过扫描使标志位大于0的位自动加一,这样原来设置的蛇头变为蛇身,而新蛇头则为初始方向的下一个坐标。而因为我们墙和其他物体的标志位都为负数,所以不受影响。

for(i=1;i<High-1;i++)                                                     //扫描所有二维码数组,把所有>0的元素+1 *for(j=1;j<Width-1;j++)if (map[i][j]>0)    map[i][j]++;                              //扫描到坐标上的数,意思是使贪吃蛇运动起来 ,其他物体不变 

然后蛇头动起来,蛇身也要动起来,并且因为如果长度不变,蛇头移动了一个,那蛇尾自然也要移动。而因为 map[i][j]++,所以蛇尾的表示为变为6,所以我们这里通过if(map[i][j]==6+ledth) map[i][j]=0,是老的蛇尾变为0。

if(map[i][j]==6+ledth)  map[i][j]=0;                     //重新开始继续扫描

然后旧蛇头的位置因为+1,标志位变为2,所以变为蛇身。而新蛇头的位置则根据旧蛇头和移动方向来决定。所以我们要将旧蛇头的位置记录下来,在进行相应加减赋值给新蛇头。
具体代码如下:

if(map[i][j]==2)   {oldhead_x=i;oldhead_y=j;}          //把旧的坐标赋值给oldhead ,记录蛇头位置//新蛇头位置与老蛇头的位置关系 if(movedirection==4){                                          //这里的x就是y,y就是x newhead_y=oldhead_y+1;                       newhead_x=oldhead_x;               //向右 ,将旧蛇头的位置赋值给新蛇头 }
    movedirection=4;                     //设置蛇头的初始方向 int ledth=0;            //定义增加的长度 int oldhead_x,oldhead_y,newhead_x,newhead_y; for(i=1;i<High-1;i++)                                                     //扫描所有二维码数组,把所有>0的元素+1 *for(j=1;j<Width-1;j++)if (map[i][j]>0)    map[i][j]++;                              //扫描到坐标上的数,意思是使贪吃蛇运动起来 ,其他物体不变 //数组内元素值为6时,置0,元素值为2的坐标定义为旧蛇头的位置 for(i=1;i<High-1;i++){                                            //i代表的y,j代表的是x for(j=1;j<Width-1;j++){if(map[i][j]==6+ledth)  map[i][j]=0;                     //重新开始继续扫描  if(map[i][j]==2)   {oldhead_x=i;oldhead_y=j;}          //把旧的坐标赋值给oldhead ,记录蛇头位置 }}//新蛇头位置与老蛇头的位置关系 if(movedirection==4){                                          //这里的x就是y,y就是x newhead_y=oldhead_y+1;                       newhead_x=oldhead_x;               //向右 ,将旧蛇头的位置赋值给新蛇头 }if(movedirection==1){                 //向上 newhead_y=oldhead_y;newhead_x=oldhead_x-1;}if(movedirection==2){                //向下 newhead_y=oldhead_y;newhead_x=oldhead_x+1;}if(movedirection==3){              //向左 newhead_y=oldhead_y-1;newhead_x=oldhead_x;}

第四步,解决了贪吃蛇问题,我们就来设计食物和炸弹
因为我们是通过动态扫描的方式来显示不同的物体嘛,所以像食物和炸弹都需要各自的坐标,但是我们总不能自己来设置食物产生的点吧,当然是希望它是随机产生在地图的任意位置(但是不能出现在墙上和蛇身上),所以这里我们采用随机函数来产生随机坐标这里的(High-4)+2和(Width-4)+2是为了防止食物出现在墙上。

	//设计食物的元素值为-2srand(time(NULL));  //设计随机数种子 Food_x=rand()%(High-4)+2;     //生成食物随机的坐标位置  Food_y=rand()%(Width-4)+2;map[Food_x][Food_y]=-2;      //设置食物的标志位为-2

当然我们也要防止食物出现在蛇身上,所以这里当食物出现的坐标上面的标志位大于等于2,就再重新生成一个食物的随机坐标。

if(map[Food_x][Food_y]>=2)                  //防止食物出现在蛇身上 {Food_x=rand()%(High-4)+2;           Food_y=rand()%(Width-4)+2;map[Food_x][Food_y]=-2;}

炸弹的原理跟食物是一样的,这里就展示代码
先是随机产生炸弹的位置,然后根据开始选的炸弹数执行相应代码

    boom_x=rand()%(High-4)+2;     boom_y=rand()%(Width-4)+2;map[boom_x][boom_y]=-3;if(zd1){                                     //选1则出现两个炸弹 boom_x1=rand()%(High-4)+2;     boom_y1=rand()%(Width-4)+2;map[boom_x1][boom_y1]=-4;}                   //使其赋值标志位为-4 if(zd2){                                    //选2则出现三个炸弹 boom_x1=rand()%(High-4)+2;                   boom_y1=rand()%(Width-4)+2;map[boom_x1][boom_y1]=-4;	boom_x2=rand()%(High-4)+2;     boom_y2=rand()%(Width-4)+2;map[boom_x2][boom_y2]=-5; } 

第五步,蛇和食物与炸弹都有了,我们该写吃到食物长度加长和分数加1,吃到炸弹生命值减1。
这里当我们吃到食物后,执行分数加1并且长度加1,然后再重新生成一个食物,其坐标也是随机函数生成的。

	//吃到食物if((oldhead_x==Food_x)&&(oldhead_y==Food_y)) {score++;srand(time(NULL));ledth++;Food_x=rand()%(High-4)+2;Food_y=rand()%(Width-4)+2;map[Food_x][Food_y]=-2;if(map[Food_x][Food_y]>=2)                      //防止食物出现在蛇身上{Food_x=rand()%(High-4)+2;Food_y=rand()%(Width-4)+2;map[Food_x][Food_y]=-2;} 	}

然后就是吃到炸弹后生命值减小并且再重新生成一个炸弹,其炸弹的坐标也是有随机函数生成的。当然两个、三个炸弹的原理都是一样的。这里就举例一个炸弹

	//吃到炸弹if((oldhead_x==boom_x)&&(oldhead_y==boom_y)) {--shenming;srand(time(NULL));boom_x=rand()%(High-4)+2;boom_y=rand()%(Width-4)+2;map[boom_x][boom_y]=-3; 	}

当然还有比如蛇吃到自己身体和撞到墙上的情况,吃到一个身位生命值就减1,当减到0就会游戏结束。而撞到墙上则游戏直接结束。

	//吃到自己的身体if(map[newhead_x][newhead_y]>2) {--shenming;}//判断失败,撞到墙 if(map[newhead_x][newhead_y]==-1){                         printf("game over\n");exit(0);}//生命值为0则结束游戏 if(shenming==0){ printf("game over\n");} 

第六步,就是写相关操控,我们要用上下左右来去控制蛇的运动方向以及改变蛇的运动速度和暂停以及退出。

 //键盘输入判断
void keyboard(){char ch;if(kbhit()){ch=getch();                   if(ch=='a') movedirection=3;               //向左 if(ch=='d') movedirection=4;               //向右 if(ch=='w') movedirection=1;               //向上 if(ch=='s') movedirection=2;               //向下 if(ch=='k') {sudo=sudo+20;}                //速度加快 if(ch=='l') sudo=0;                       //速递变为初始值 if(ch=='\033') exit(0);                   //按下esc可以退出 if(ch==32)  system("pause");             //按下空格键可以暂停 }if(sudo==240) {sudo=0;}
}

最后我们写一下游戏规则,这里打印在游戏地图的下面

	printf("|游戏规则:1.通过awsd来进行上下左右控制贪吃蛇,按k来增加速度,按L使速度初始化       |\n");          //游戏规则 printf("|          2.按空格键可以暂停游戏,按esc键可以退出游戏                             |\n");	printf("|          3.贪吃蛇吃到炸弹则生命值减1,吃到一个食物则分数加1,吃到自己生命值减1     |\n"); printf("|          4.如果往蛇自己的现态反方向运动,则吃到一个身位减一个生命值              |\n"); printf("|          5.字母Q代表炸弹,字母$代表食物                                          |\n"); printf("|          6.生命值为0则游戏结束                                                   |\n");printf("score:%d\n",score);printf("生命值:%d\n",shenming); 

好了写到这里,简单版贪吃蛇已经讲解完,感兴趣的朋友们可以自己做一下。
这里分享源代码给大家
代码链接:https://download.csdn.net/download/OMGMac/19354774

本人水平有限,上述信息仅供参考,如有错误和不妥之处,请多多指教。
另外创作不易,请勿抄袭,如果有帮助到大家的话希望大家可以点个赞,谢谢~


http://chatgpt.dhexx.cn/article/Ec8xRxG9.shtml

相关文章

C语言实现贪吃蛇(简易)

文章目录 目录 文章目录 前言 一、游戏功能和效果 1.游戏功能 2.游戏效果 二. 游戏初步实现 1.确定地图大小 2.创建蛇对象&#xff0c;食物对象 3.初始化蛇 4.生成随机食物 5.画蛇 6.画食物 7. 游戏内移动控制 1.当按上下左右时移动方向改变 。 2.开始游戏时的默认方向 8.判…

C语言贪吃蛇小游戏,贪吃蛇C语言代码实现大全

一、C语言贪吃蛇代码实现前言 设计贪吃蛇游戏的主要目的是让大家夯实C语言基础&#xff0c;训练编程思维&#xff0c;培养解决问题的思路&#xff0c;领略多姿多彩的C语言。 贪吃蛇是非常经典的一款游戏&#xff0c;本次我们模拟在控制台实现贪吃蛇游戏&#xff0c;也就是实现…

C语言实现贪吃蛇[内附详细步骤]

C语言贪吃蛇项目 今天给分享一下使用C语言写个贪吃蛇小游戏&#xff0c;主要包含以下10部分内容&#xff1a; 1、windows光标定位与隐藏 2、欢迎界面 3、打印围墙 4、产生食物 5、初始化蛇身 6、响应按键 7、蛇身运动 8、碰撞检测 9、结束界面 10、程序运行 windows…

C语言实现贪吃蛇小游戏!(超简单详细)详细思路+源码分享

贪吃蛇&#xff08;也叫做贪食蛇&#xff09;游戏是一款休闲益智类游戏&#xff0c;有PC和手机等多平台版本。既简单又耐玩。该游戏通过控制蛇头方向吃蛋&#xff0c;从而使得蛇变得越来越长。 我们的今天的目标就是&#xff1a;用C语言来实现一个贪吃蛇项目&#xff0c;也不用…

C语言 贪吃蛇

基于C语言编写的贪吃蛇 编写环境&#xff1a;VS2019x86 这是一个基于C语言链表开发的贪吃蛇游戏 其实贪吃蛇游戏要解决的主要问题就是 1、这个游戏的基本组成元素和数据结构 2、如何初始化贪吃蛇并正常行走 3、如何判断事件发生 代码中运用到了键盘虚拟键判断、终端窗口大小的…

游戏贪吃蛇(c语言)

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

C语言实现贪吃蛇(详细版)

一、需要掌握的知识&#xff1a; C语言基础语法&#xff08;结构体、指针、链表&#xff09;、<windows.h>库、<stdlib.h>库、<time.h>库中的一些函数&#xff08;不需要额外学习&#xff0c;本文后面会讲贪吃蛇需要用到的相关函数&#xff09; 由于作者水平…

贪吃蛇(C语言实现)

文章目录 游戏说明游戏效果展示游戏代码游戏代码详解游戏框架构建隐藏光标光标跳转初始化界面颜色设置初始化蛇随机生成食物打印蛇与覆盖蛇移动蛇游戏主体逻辑函数执行按键判断得分与结束从文件读取最高分更新最高分到文件主函数 游戏说明 游戏界面当中没有打印相关的按键说明…

SDRAM控制器(初始化)

SDRAM控制器&#xff08;初始化&#xff09; 文章目录 SDRAM控制器&#xff08;初始化&#xff09;初始化模块时序逻辑图代码仿真结果 初始化模块 SDRAM 在上电之后&#xff0c;执行正常操作之前需要被初始化&#xff0c;实际上就是对上文提到的SDRAM 内部逻辑控制单元进行初始…

SDRAM 控制器设计基本完结

项目可以拓展的地方&#xff1a; 1、接口为AXI 2、接口为AXI与AXI DMA 交互 2、优化读写时序&#xff0c;使得SDRAM输出效率最大&#xff1b; 总结&#xff1a; 项目不足&#xff1a;没有进行效率的优化&#xff0c;无地址映射&#xff0c;无外接交互接口&#xff0c;功能单一…

SDRAM读写控制

SDRAM读写控制器&#xff0c;这里分为三个部分&#xff0c;分别是SDRAM的基本操作实现&#xff0c;SDRAM控制器&#xff0c;封装成FIFO,以方便使用。 一、SDRAM的基本操作&#xff1a;初始化模块、自动刷新模块、写操作模块、读操作模块、SDRAM仲裁模块&#xff0c;顶层模块。 …

SDRAM 控制器(二)——初始化模块

1、初始化模块 SDRAM 的初始化是芯片上电后必须进行的一项操作&#xff0c;只有进行了初始化操作的 SDRAM 芯片才可被正常使用。SDRAM 的初始化是一套预先定义好的流程&#xff0c;除此之外的其 他操作会导致 SDRAM 出现不可预知的后果。 初始化时序图&#xff1a; CK&#xf…

SDRAM详细介绍

概念介绍&#xff1a; SDRAM&#xff1a;Synchronous Dynamic Random Access Memory&#xff0c;同步动态随机存储器。同步是指其时钟频率和CPU前端总线的系统时钟相同&#xff0c;并且内部命令的发送与数据的传输都以它为基准&#xff1b;动态是指存储阵列需要不断的刷新来保证…

sdram简易控制器设计

耗时一周&#xff0c;终于完成sdram简易控制器的所有代码设计&#xff0c;其中感谢开源骚客 – 邓堪文老师在b站发布的相关视频学习教材&#xff1b;其中仿真模块及所使用到的sdram仿真文件来源于开源骚客&#xff1b; 因为时间较为紧迫&#xff0c;其中就不做代码的一些注释&…

基于FPGA的SDRAM控制器设计(一)

基于FPGA的SDRAM控制器设计&#xff08;一&#xff09; 1. SDRAM控制器整体框架2.UART_RX模块3.UART_TX模块4. RX与TX模块的整合5.需要注意的问题6.代码7.参考资料 1. SDRAM控制器整体框架 图1.1整体框架 PC端通过串口模块UART_RX发送读写命令以及数据到Cmd_encode模块&#xf…

基于FPGA的SDRAM控制器设计(1)

基于FPGA的SDRAM初始化配置 SDRAM简述SDRAM的引脚及作用SDRAM初始化时序控制SDRAM上电时序代码SDRAM测试模块的代码仿真测试结果参考文献总结 SDRAM简述 SDRAM&#xff08; Synchronous Dynamic Random Access Memory&#xff09;&#xff0c;同步动态随机存储器。同步是指 Me…

FPGA进阶(3):SDRAM读写控制器的设计与验证

文章目录 第50讲&#xff1a;SDRAM读写控制器的设计与验证理论部分设计与实现1. sdram_ctrlsdram_initsdram_a_refsdram_writesdram_readsdram_arbitsdram_ctrl 2. sdram_topfifo_ctrlsdram_top 3. uart_sdramuart_rxuart_txfifo_readuart_sdram 第50讲&#xff1a;SDRAM读写控…

SDRAM

简介、优缺点、历史 1、译为“同步动态随机存取内存”&#xff0c;区别于异步DRAM。SRAM是异步静态存储器。 2、同步(Synchronous)&#xff1a;与通常的异步 DRAM 不同&#xff0c; SDRAM 存在一个同步接口&#xff0c;其工作时钟的时钟频率与对应控制器(CPU/FPGA上的读写控制…

关于SDRAM存储器

一、对SDRAM的初步认识 1.1 什么是SDRAM SDRAM&#xff08;Synchronous Dynamic Random Access Memory&#xff09;&#xff0c;同步动态随机存取存储器。 同步&#xff1a;工作频率与对应控制器的系统时钟频率相同&#xff0c;且内存内部的命令以及数据的传输都以此为基准 …

内存控制器与SDRAM

内存接口概念&#xff1a; 通常ARM芯片内置的内存很少&#xff0c;要运行Linux&#xff0c;需要扩展内存。ARM9扩展内存使用SDRAM内存&#xff0c;ARM11使用 DDR SDRAM。S3C2440通常外接32位64MBytes的SDRAM&#xff0c;采用两片16位32M的SDRAM芯片&#xff0c;SDRAM芯片通过地…