• 欢迎访问C语言网www.dotcpp.com 比赛栏每月有奖月赛!举办比赛联系QQ:2045302297
  • 问题反馈、粉丝交流 QQ群327452739 蓝桥杯训练群:113766799 申请群时请备注排名里的昵称
  • C语言研究中心 为您提供有图、有料、解渴的C语言专题! 欢迎讨论!

纯C语言实现贪吃蛇游戏(VC6.0)

C语言研究中心 CTO 127294次浏览 69个评论

今天笔者为大家展示C语言写的贪吃蛇游戏,让大家玩一玩自己写的游戏~ 是纯C语言哦~VC6.0开发 无问题

 

首先,开始界面:

纯C语言实现贪吃蛇游戏(VC6.0)

游戏界面如下:

纯C语言实现贪吃蛇游戏(VC6.0)

代码如下:

笔者VC6.0下编写,测试无问题,可复制代码直接到VC6源文件下,后缀为.c文件 可以编译通过运行~

  1. #include<stdio.h>
  2. #include<time.h>
  3. #include<windows.h>
  4. #include<stdlib.h>
  5. #define U 1
  6. #define D 2
  7. #define L 3
  8. #define R 4 //蛇的状态,U:上 ;D:下;L:左 R:右
  9. typedef struct SNAKE //蛇身的一个节点
  10. {
  11. int x;
  12. int y;
  13. struct SNAKE *next;
  14. }snake;
  15. //全局变量//
  16. int score=0,add=10;//总得分与每次吃食物得分。
  17. int status,sleeptime=200;//每次运行的时间间隔
  18. snake *head, *food;//蛇头指针,食物指针
  19. snake *q;//遍历蛇的时候用到的指针
  20. int endgamestatus=0; //游戏结束的情况,1:撞到墙;2:咬到自己;3:主动退出游戏。
  21. //声明全部函数//
  22. void Pos();
  23. void creatMap();
  24. void initsnake();
  25. int biteself();
  26. void createfood();
  27. void cantcrosswall();
  28. void snakemove();
  29. void pause();
  30. void gamecircle();
  31. void welcometogame();
  32. void endgame();
  33. void gamestart();
  34. void Pos(int x,int y)//设置光标位置
  35. {
  36. COORD pos;
  37. HANDLE hOutput;
  38. pos.X=x;
  39. pos.Y=y;
  40. hOutput=GetStdHandle(STD_OUTPUT_HANDLE);
  41. SetConsoleCursorPosition(hOutput,pos);
  42. }
  43. void creatMap()//创建地图
  44. {
  45. int i;
  46. for(i=0;i<58;i+=2)//打印上下边框
  47. {
  48. Pos(i,0);
  49. printf("■");
  50. Pos(i,26);
  51. printf("■");
  52. }
  53. for(i=1;i<26;i++)//打印左右边框
  54. {
  55. Pos(0,i);
  56. printf("■");
  57. Pos(56,i);
  58. printf("■");
  59. }
  60. }
  61. void initsnake()//初始化蛇身
  62. {
  63. snake *tail;
  64. int i;
  65. tail=(snake*)malloc(sizeof(snake));//从蛇尾开始,头插法,以x,y设定开始的位置//
  66. tail->x=24;
  67. tail->y=5;
  68. tail->next=NULL;
  69. for(i=1;i<=4;i++)
  70. {
  71. head=(snake*)malloc(sizeof(snake));
  72. head->next=tail;
  73. head->x=24+2*i;
  74. head->y=5;
  75. tail=head;
  76. }
  77. while(tail!=NULL)//从头到为,输出蛇身
  78. {
  79. Pos(tail->x,tail->y);
  80. printf("■");
  81. tail=tail->next;
  82. }
  83. }
  84. int biteself()//判断是否咬到了自己
  85. {
  86. snake *self;
  87. self=head->next;
  88. while(self!=NULL)
  89. {
  90. if(self->x==head->x && self->y==head->y)
  91. {
  92. return 1;
  93. }
  94. self=self->next;
  95. }
  96. return 0;
  97. }
  98. void createfood()//随机出现食物
  99. {
  100. snake *food_1;
  101. srand((unsigned)time(NULL));
  102. food_1=(snake*)malloc(sizeof(snake));
  103. while((food_1->x%2)!=0) //保证其为偶数,使得食物能与蛇头对其
  104. {
  105. food_1->x=rand()%52+2;
  106. }
  107. food_1->y=rand()%24+1;
  108. q=head;
  109. while(q->next==NULL)
  110. {
  111. if(q->x==food_1->x && q->y==food_1->y) //判断蛇身是否与食物重合
  112. {
  113. free(food_1);
  114. createfood();
  115. }
  116. q=q->next;
  117. }
  118. Pos(food_1->x,food_1->y);
  119. food=food_1;
  120. printf("■");
  121. }
  122. void cantcrosswall()//不能穿墙
  123. {
  124. if(head->x==0 || head->x==56 ||head->y==0 || head->y==26)
  125. {
  126. endgamestatus=1;
  127. endgame();
  128. }
  129. }
  130. void snakemove()//蛇前进,上U,下D,左L,右R
  131. {
  132. snake * nexthead;
  133. cantcrosswall();
  134. nexthead=(snake*)malloc(sizeof(snake));
  135. if(status==U)
  136. {
  137. nexthead->x=head->x;
  138. nexthead->y=head->y-1;
  139. if(nexthead->x==food->x && nexthead->y==food->y)//如果下一个有食物//
  140. {
  141. nexthead->next=head;
  142. head=nexthead;
  143. q=head;
  144. while(q!=NULL)
  145. {
  146. Pos(q->x,q->y);
  147. printf("■");
  148. q=q->next;
  149. }
  150. score=score+add;
  151. createfood();
  152. }
  153. else //如果没有食物//
  154. {
  155. nexthead->next=head;
  156. head=nexthead;
  157. q=head;
  158. while(q->next->next!=NULL)
  159. {
  160. Pos(q->x,q->y);
  161. printf("■");
  162. q=q->next;
  163. }
  164. Pos(q->next->x,q->next->y);
  165. printf(" ");
  166. free(q->next);
  167. q->next=NULL;
  168. }
  169. }
  170. if(status==D)
  171. {
  172. nexthead->x=head->x;
  173. nexthead->y=head->y+1;
  174. if(nexthead->x==food->x && nexthead->y==food->y) //有食物
  175. {
  176. nexthead->next=head;
  177. head=nexthead;
  178. q=head;
  179. while(q!=NULL)
  180. {
  181. Pos(q->x,q->y);
  182. printf("■");
  183. q=q->next;
  184. }
  185. score=score+add;
  186. createfood();
  187. }
  188. else //没有食物
  189. {
  190. nexthead->next=head;
  191. head=nexthead;
  192. q=head;
  193. while(q->next->next!=NULL)
  194. {
  195. Pos(q->x,q->y);
  196. printf("■");
  197. q=q->next;
  198. }
  199. Pos(q->next->x,q->next->y);
  200. printf(" ");
  201. free(q->next);
  202. q->next=NULL;
  203. }
  204. }
  205. if(status==L)
  206. {
  207. nexthead->x=head->x-2;
  208. nexthead->y=head->y;
  209. if(nexthead->x==food->x && nexthead->y==food->y)//有食物
  210. {
  211. nexthead->next=head;
  212. head=nexthead;
  213. q=head;
  214. while(q!=NULL)
  215. {
  216. Pos(q->x,q->y);
  217. printf("■");
  218. q=q->next;
  219. }
  220. score=score+add;
  221. createfood();
  222. }
  223. else //没有食物
  224. {
  225. nexthead->next=head;
  226. head=nexthead;
  227. q=head;
  228. while(q->next->next!=NULL)
  229. {
  230. Pos(q->x,q->y);
  231. printf("■");
  232. q=q->next;
  233. }
  234. Pos(q->next->x,q->next->y);
  235. printf(" ");
  236. free(q->next);
  237. q->next=NULL;
  238. }
  239. }
  240. if(status==R)
  241. {
  242. nexthead->x=head->x+2;
  243. nexthead->y=head->y;
  244. if(nexthead->x==food->x && nexthead->y==food->y)//有食物
  245. {
  246. nexthead->next=head;
  247. head=nexthead;
  248. q=head;
  249. while(q!=NULL)
  250. {
  251. Pos(q->x,q->y);
  252. printf("■");
  253. q=q->next;
  254. }
  255. score=score+add;
  256. createfood();
  257. }
  258. else //没有食物
  259. {
  260. nexthead->next=head;
  261. head=nexthead;
  262. q=head;
  263. while(q->next->next!=NULL)
  264. {
  265. Pos(q->x,q->y);
  266. printf("■");
  267. q=q->next;
  268. }
  269. Pos(q->next->x,q->next->y);
  270. printf(" ");
  271. free(q->next);
  272. q->next=NULL;
  273. }
  274. }
  275. if(biteself()==1) //判断是否会咬到自己
  276. {
  277. endgamestatus=2;
  278. endgame();
  279. }
  280. }
  281. void pause()//暂停
  282. {
  283. while(1)
  284. {
  285. Sleep(300);
  286. if(GetAsyncKeyState(VK_SPACE))
  287. {
  288. break;
  289. }
  290. }
  291. }
  292. void gamecircle()//控制游戏
  293. {
  294.  
  295. Pos(64,15);
  296. printf("不能穿墙,不能咬到自己\n");
  297. Pos(64,16);
  298. printf("用↑.↓.←.→分别控制蛇的移动.");
  299. Pos(64,17);
  300. printf("F1 为加速,F2 为减速\n");
  301. Pos(64,18);
  302. printf("ESC :退出游戏.space:暂停游戏.");
  303. Pos(64,20);
  304. printf("c语言研究中心 www.dotcpp.com");
  305. status=R;
  306. while(1)
  307. {
  308. Pos(64,10);
  309. printf("得分:%d ",score);
  310. Pos(64,11);
  311. printf("每个食物得分:%d分",add);
  312. if(GetAsyncKeyState(VK_UP) && status!=D)
  313. {
  314. status=U;
  315. }
  316. else if(GetAsyncKeyState(VK_DOWN) && status!=U)
  317. {
  318. status=D;
  319. }
  320. else if(GetAsyncKeyState(VK_LEFT)&& status!=R)
  321. {
  322. status=L;
  323. }
  324. else if(GetAsyncKeyState(VK_RIGHT)&& status!=L)
  325. {
  326. status=R;
  327. }
  328. else if(GetAsyncKeyState(VK_SPACE))
  329. {
  330. pause();
  331. }
  332. else if(GetAsyncKeyState(VK_ESCAPE))
  333. {
  334. endgamestatus=3;
  335. break;
  336. }
  337. else if(GetAsyncKeyState(VK_F1))
  338. {
  339. if(sleeptime>=50)
  340. {
  341. sleeptime=sleeptime-30;
  342. add=add+2;
  343. if(sleeptime==320)
  344. {
  345. add=2;//防止减到1之后再加回来有错
  346. }
  347. }
  348. }
  349. else if(GetAsyncKeyState(VK_F2))
  350. {
  351. if(sleeptime<350)
  352. {
  353. sleeptime=sleeptime+30;
  354. add=add-2;
  355. if(sleeptime==350)
  356. {
  357. add=1; //保证最低分为1
  358. }
  359. }
  360. }
  361. Sleep(sleeptime);
  362. snakemove();
  363. }
  364. }
  365. void welcometogame()//开始界面
  366. {
  367. Pos(40,12);
  368.  
  369. system("title c语言研究中心 www.dotcpp.com");
  370. printf("欢迎来到贪食蛇游戏!");
  371. Pos(40,25);
  372. system("pause");
  373. system("cls");
  374. Pos(25,12);
  375. printf("用↑.↓.←.→分别控制蛇的移动, F1 为加速,2 为减速\n");
  376. Pos(25,13);
  377. printf("加速将能得到更高的分数。\n");
  378. system("pause");
  379. system("cls");
  380. }
  381. void endgame()//结束游戏
  382. {
  383. system("cls");
  384. Pos(24,12);
  385. if(endgamestatus==1)
  386. {
  387. printf("对不起,您撞到墙了。游戏结束.");
  388. }
  389. else if(endgamestatus==2)
  390. {
  391. printf("对不起,您咬到自己了。游戏结束.");
  392. }
  393. else if(endgamestatus==3)
  394. {
  395. printf("您的已经结束了游戏。");
  396. }
  397. Pos(24,13);
  398. printf("您的得分是%d\n",score);
  399. exit(0);
  400. }
  401. void gamestart()//游戏初始化
  402. {
  403. system("mode con cols=100 lines=30");
  404. welcometogame();
  405. creatMap();
  406. initsnake();
  407. createfood();
  408. }
  409. int main()
  410. {
  411. gamestart();
  412. gamecircle();
  413. endgame();
  414. return 0;
  415. }

C语言研究中心(www.dotcpp.com)

C语言网提供「C语言、C++、算法竞赛」在线课程,全部由资深研发工程师或ACM金牌大佬亲授课,更科学、全面的课程体系,以在线视频+在线评测的学习模式学习,学练同步,拒绝理论派,真正学会编程!还有奖学金等增值福利等你!

C语言网, 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明纯C语言实现贪吃蛇游戏(VC6.0)
喜欢 (532)
[jinyangH@aliyun.com]
分享 (0)
发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
(69)个小伙伴在吐槽
  1. ?前面包含的是什么头文件啊?
    ghost1012016-09-19 11:13 回复
    • 已经补充.
      root2016-09-19 21:41 回复
      • 请问你是写这个代码的人吗,我想问一些问题
        一个不会写代码的小渣渣2017-02-03 14:47 回复
      • 还是运行不了啊
        表笔2020-01-08 13:41 回复
  2. 53行注释分行错误
    vagrant2016-09-28 19:46 回复
    • 需要分行写,注释太多了
      CTO2016-10-22 14:11 回复
  3. 是不是一定要用vc6.0编译,为什么编译了食物出不来?
    stark2016-10-22 12:27 回复
    • 可以不用,CB、dev应该也可以,可以试试,有问题交流
      CTO2016-10-22 14:11 回复
      • 我是源代码直接复制的,可是运行起来食物出不来,我用的dev c++
        stark2016-10-22 14:15 回复
        • 我用dev c++也刷不出食物出来
          ECHO2016-12-20 14:41 回复
          • 代码已经更新,可以正常使用了!
            CTO2017-02-03 17:43
  4. 吃了10个食物之后 就不刷新食物了,而且暂停了一会之后,控制台窗口就自己消失了。
    KOOben2016-10-23 22:04 回复
  5. 作者是谁,我想问一些问题
    一个不会写代码的小渣渣2017-01-13 13:22 回复
    • 你好,有什么问题呢
      CTO2017-02-03 17:43 回复
      • 我也才学一点点c语言的东西 while(q->next->next!=NULL)里面的那个小箭头什么的是什么意思 好多行代码里都有这个 麻烦您解释一下 谢谢!
        一个不会写代码的小渣渣2017-02-06 12:22 回复
        • ->是指针的指向的意思
          word2017-02-06 19:14 回复
        • 表示指向某个指针
          m2019-10-18 17:04 回复
      • 为什么我复制到电脑上之后,编译时提示第一个printf错误
        2019-01-26 12:26 回复
      • 为什么这个后面蛇走的位置都是黑色的
        handshake2022-02-03 15:21 回复
  6. 刷不出食物来是因为创造食物的那个函数里food_1->x没有初值,把1赋给它就行了。
    150836573142017-02-09 22:03 回复
    • 试了反而gg了
      zcj2018-01-03 20:10 回复
    • 在哪里赋值,能详细一点说明嘛
      7242021-03-19 08:40 回复
      • 可以使用 do while 先执行再判断 :smile:
        底料的奢华2022-05-01 22:35 回复
  7. createfood函数里的递归部分总感觉有问题,首先while(q->next==NULL)是不是应该改为while(q!=NULL),同时递归终止后一步步回调,q已经指向尾指针的next,再执行一次q=q->next会出问题吧,同时那个food_1都已经被free了,之后还对food_1-x和y进行了操作~~~~
    易关建2017-02-23 09:33 回复
  8. 我用codeblocks编写,在我的电脑上运行没问题,但把exe文件拿到别的电脑上运行就有各种问题,请问这怎么解决呢。。
    BIG_RED2017-05-25 14:11 回复
  9. 楼主!我用的C-Free 4.0 运行程序,不出食物。能指导一下吗?
    草木年华2017-06-08 11:05 回复
  10. 楼主!刷不出食物可能是食物与墙重合了,是不是要写一个程序判断是否与墙重合?
    草木年华2017-06-08 11:37 回复
  11. 变成出来以后 没看到食物
    月亮2017-06-15 14:19 回复
  12. 我用的是Dev C++,出来的时候没有食物,
    潜行暗影2017-08-01 07:03 回复
    • createfood这个函数有错误第二个while循环就像楼上说的一样条件需要改一下,第一个while循环中作为判断条件的food_1没有赋值,用的还是堆中那个原始的未知的值将其改为 do{ food02->x=rand()%52+2; } while((food02->x%2)!=0); //保证其为偶数,使得食物能与蛇头对齐 就可以了
      白色的加菲猫2019-02-19 23:18 回复
      • do{ food02->x=rand()%52+2;,评论中的这串代码放在哪里
        2020-06-10 18:17 回复
  13. 如果有教程,就好了,直接给,还是不会啊,只能玩
    快乐的叮当2017-08-04 13:06 回复
    • 不难的,一个一个百度过去不懂得地方理解一下,我也是刚学的,但是你要会链表,感觉是里面最难的东西了,多百度
      无聊星期三2017-09-05 20:29 回复
  14. 1.操作有延迟 2.8个后不刷食物
    dzyfk2017-09-04 11:20 回复
  15. 运行到210分时,无法找到食物
    ling2017-11-16 11:33 回复
  16. 楼主 没有食物是为什么
    zcj2018-01-03 20:10 回复
  17. 您好,我在运行您的代码时发现这个食物消失的问题。我发现是createfood函数中第二个while循环里的条件写错了。。。 第二个循环本意是在避免食物刷在蛇身上。但是这个循环根本就进不去。。。入口条件错误了应当改成“!=”才对。。。这样就避免了食物刷在蛇身上的问题。。。但是我还是不明白为什么刷在蛇身上会导致食物消失。并且当我改成“!=”时,程序在吃一定数量的食物后就爆炸了。。。求教。。。
    过来看这个贪吃蛇的2018-01-04 21:50 回复
    • 我把条件改成"!=",吃了十几个,也没有遇到程序爆炸的问题,另外,食物刷在蛇身上时会满足if(q->x==newfood->x && q->y==newfood->y)条件,就会执行free(food_1);语句,释放了food_1的内存,即food_1不再存在,下面又用 createfood();重新产生了一个食物。
      李狗嗨2122018-02-12 22:23 回复
      • 问一下代码怎么改的,食物看不到
        校友2018-04-13 18:19 回复
        • vc++6.0可以,vs2017可以,但是codeblocks刷不到食物
          爱上公司发的2018-12-21 17:16 回复
          • 蛇自身能动是在哪个函数实现的
            冰阳2018-12-24 14:16
          • 直接复制行吗?
            2019-02-28 23:40
    • 请问您现在解决问题了吗 我也遇到跟你相同的问题
      多吉2018-11-22 17:20 回复
  18. 我也有一个疑问,为什么没有吃到食物时,循环显示条件是while(q->next->next!=NULL),而不是while(q->next!=NULL),望大佬给我解答一下
    李狗嗨2122018-02-12 22:58 回复
  19. 判断是否咬到自己那里没看懂,为什么95行那里要把蛇头的下一个节点赋值给它,而不是用蛇头自己去判断
    141lin2018-03-14 19:52 回复
  20. 为啥食物看不到的
    校友2018-04-13 18:18 回复
  21. 我用DEVC++运行,发现食物有时会刷在边界强上直接GG
    一个人2018-04-23 18:51 回复
  22. 判断第一个while的时候food_1->x没有赋值,改成do while语句就可以了
    一条咸鱼2018-05-25 20:22 回复
    • 能发给我看一下怎么改的么
      C小书童2018-07-09 15:41 回复
  23. 没有食物
    suruijiao9222018-06-19 13:34 回复
  24. 把exit去掉蛇身不消失,是为啥,bug出在哪了
    ggg2018-06-28 16:50 回复
  25. 很好,搜索别的贪吃蛇源代码运行时一堆报错,这个代码一次运行成功!非常感谢!
    银河2018-10-02 00:05 回复
  26. 你确实他一开始动的了,一堆问题
    无缘2018-12-17 23:42 回复
  27. 假设没有刷到蛇身,你又不停的调用food函数,没有释放内存,那么食物内存会爆炸吗?
    无缘2018-12-19 11:39 回复
  28. 请问有这个代码的全部注释吗?
    一如少年2019-01-06 16:07 回复
  29. 能解决下不能刷食物问题吗,都太监了
    无缘2019-01-28 23:26 回复
  30. createfood函数里面不需要这么写链表呀,直接一个普通的结构体搞定,写链表反而搞复杂了。
    day02019-02-09 16:04 回复
  31. 你好,不知道为什么?compile的时候没有错误,但是运行的时候显示有1个错误
    立志做码农2019-04-22 19:51 回复
  32. 作者你好,你这份贪吃蛇代码我发现了一个问题,就是在运动过程中蛇头的纵坐标变化,向上的时候纵坐标不断减少,在10之后应该是9,8,7,6等,结果居然变成了90,80,70,60,这种情况在吃一个食物的时候很少出现错误,一旦同时产生两个或者更多的食物,就会出现吃到食物分数不加的情况
    五月2019-06-24 08:32 回复
  33. 我的为啥没有失望
    邀月2019-12-06 22:39 回复
  34. 我的为啥运行后没有食物
    邀月2019-12-06 22:41 回复
  35. 为什么地图右边的墙会移动,而且蛇身移动还有影子?timesleep的问题吗的问题吗
    Surene2019-12-09 09:03 回复
  36. 楼主,我想要在“暂停”,“继续”后加上“新游戏”选项,应该怎么做?
    www2019-12-25 09:51 回复
  37. 我的CB也没有食物
    阿萨德2020-02-02 10:12 回复
  38. 刚运行了一下,什么玩意都是。蛇屁股后面拖那么老长一条,是窜稀了吗?
    moo2020-11-28 21:59 回复
    • 两个空格
      jia2021-01-24 09:56 回复
      • 请问怎么解决哇
        。。。2022-12-18 10:22 回复
  39. 这个蛇的运动,可以去尾、添头来模拟,不然那个组成墙的方块就会跟着运动
    1212021-06-11 23:42 回复
  40. 为什么蛇不动?
    2021-09-12 09:07 回复