鱼C论坛

 找回密码
 立即注册
查看: 3815|回复: 12

[萌新报道] 看完小甲鱼老师的视频后自己做了一个贪吃蛇(qwq不喜勿喷)

[复制链接]
发表于 2018-5-4 21:19:10 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  1. #include <stdio.h>
  2. #include <windows.h>
  3. #include <conio.h>
  4. #include <time.h>

  5. #define frame_height 25 //边框上下长
  6. #define frame_width 50   //边框左右宽
  7. #define UP 'w'    //宏定义, 将以下出现的up替换成w
  8. #define DOWN 's'  //同上
  9. #define WEST 'a'  //同上
  10. #define RIGHT 'd' //同上

  11. struct Food   // 定义一个结构体 确认食物坐标
  12. {
  13.         int x;
  14.         int y;
  15. }food;
  16. struct Snake   // 定义一个结构体 用数组的方式储存蛇的每一节身体坐标、身体总长度(节点数量)和速度
  17. {
  18.         int x[100];
  19.         int y[100];
  20.         int speed;
  21.         int length;
  22. }snake;
  23. char ch, tempch;  //蛇的方向, 蛇暂时的方向(后面改变蛇的方向会用到)
  24. int i, temp_x, temp_y, temp_x2, temp_y2, score; //i循环用 ,两个暂时的坐标(后面完成蛇的移动会用到), 得分

  25. int main(void)
  26. {
  27.         void screen(void);  //定义一个函数,用来打印界面
  28.         void initial_data(void); //定义一个函数,用来初始化蛇的身体和食物的位置
  29.         void update_food(void); //定义一个函数,用来生成一个食物
  30.         void move_snake(void); //定义一个函数,用来移动蛇
  31.         void get_speed(void); //定义一个函数,用来确定蛇移动的速度
  32.         int if_dead(void);  //定义一个函数,用来确定游戏是否结束
  33.         void end(void);  //定义一个函数,用来打印结束画面
  34.         void gotoxy(int x, int y); //定义一个函数,用来移动光标到屏幕上对应的位置(屏幕看成一个坐标系,左上角为原点,向下为X轴,向右为Y轴)
  35.        
  36.         while(1)
  37.         {
  38.                 initial_data(); //初始化蛇的身体和食物的位置  ******这里为我了美观所以先初始化再打印界面(我函数中不完善的地方)*********
  39.                 screen();  //打印界面                         ******按照逻辑应该先打印界面的(之后定义的函数也有很多不符合逻辑的地方请体谅新手qwq)******
  40.                 while(1) //游戏开始
  41.                 {
  42.                         update_food(); //生成食物
  43.                         get_speed(); //获得蛇速度
  44.                         move_snake(); // 移动蛇
  45.                         Sleep(snake.speed); //Sleep(100),程序暂停100毫秒。
  46.                         if(if_dead()) //蛇死亡函数返回1,跳出循环即游戏结束
  47.                         {
  48.                                 break;
  49.                         }
  50.                 }
  51.                 end();
  52.                 if(getch()==27) //如果输入ESC退出程序即退出游戏
  53.                 {
  54.                         break;
  55.                 }
  56.                 else //输入不为ESC键重新开始游戏
  57.                 {
  58.                         gotoxy(12, 20); //把光标移动到(12,20)这个点
  59.                         printf("         ");  //这两句清除屏幕中“游戏结束”4个字和“!”一个字符,一个汉字两个字符所以总共打印9个空格覆盖
  60.                         continue;
  61.                 }
  62.         }

  63.         return 0;
  64. }

  65. void screen(void)
  66. {
  67.         void gotoxy(int x, int y);

  68.         for(i=0 ; i<=24 ; i++) //打印左右边框
  69.         {
  70.                 gotoxy(i, 0);
  71.                 printf("+");
  72.                 gotoxy(i, frame_width - 1);
  73.                 printf("+");
  74.         }
  75.         for(i=1; i<=48 ; i++) //打印上下边框
  76.         {
  77.                 gotoxy(0, i);
  78.                 printf("+");
  79.                 gotoxy(frame_height-1, i);
  80.                 printf("+");
  81.         }
  82.         gotoxy(6, 60);   //打印右侧的界面
  83.         printf("欢迎来到贪吃蛇(简易版)");
  84.         gotoxy(9, 60);
  85.         printf("当前得分:%d ", score);
  86.         gotoxy(12, 60);
  87.         printf("操作:'W'上,'S'下,'A'左,'D'右");
  88.         gotoxy(15, 60);
  89.         printf("按空格键开始(重新开始)");
  90.         gotoxy(18, 60);
  91.         printf("ESC键退出游戏!");
  92.         if(getch() != ' ') //如果输入不是空格键就进入下面那个循环
  93.         {
  94.                 while(1) // 直到输入空格键跳出循环,相当于按空格键开始游戏
  95.                 {
  96.                         if(getch() == ' ')
  97.                         {
  98.                                 break;
  99.                         }
  100.                 }
  101.         }
  102. }

  103. void initial_data(void)
  104. {
  105.         void gotoxy(int x, int y);
  106.         void update_food(void);
  107.        
  108.         snake.x[0] = frame_width / 3;
  109.         snake.y[0] = frame_height / 3; //蛇的坐标(X,Y)在(25/3, 50/3)处
  110.         snake.length = 3; //蛇有3节
  111.         ch = RIGHT; //蛇的方向向右;
  112.         for(i=1 ; i<=snake.length ; i++)  //从第二节蛇身开始每一节的Y坐标都比蛇头少1,循环输入除了蛇头其余身体节点的坐标
  113.         {                                 //这里循环了3次,按道理身体长度为3时除了蛇头应该只要循环两次
  114.                 snake.x[i] = snake.x[i-1];   //所以除了蛇目前身体的坐标确定以外,未来吃到食物的一节身体的坐标也是确定的(目前这节身体还不在)。
  115.                 snake.y[i] = snake.y[i-1] - 1;//目前确定的点有snake[0],snake[1],snake[2],snake[3],除了snake[3]以外蛇的身体是确实存在的
  116.                 gotoxy(snake.x[i-1], snake.y[i-1]);//所以打印了除了snake[3]的节点 (为了方便就简写成snake[i]的形式了,其实是snake.x[i], snake.y[i],以后出现同理)
  117.                 printf("*");//我用的“*”来表示蛇的身体,也可以用其他的字符表示
  118.         }
  119.         food.x = snake.x[0];
  120.         food.y = snake.y[0]; //暂定食物在蛇头位置(这里只是为了初始化食物的数据以方便后面调用update_food函数)
  121.         score = 0;
  122.         update_food();
  123. }

  124. void update_food(void)
  125. {
  126.         void gotoxy(int x, int y);

  127.         if(snake.x[0] == food.x && snake.y[0] == food.y)
  128.         {
  129.                 while(1)
  130.                 {
  131.                         srand(time(NULL)); //srand(),time(),rand()详细说明自行百度,这里的作用就是得到一个随机数
  132.                         food.x = rand()%23 + 1; //(rand()%23+1实际上是rand()%(24-1)+1,得到一个范围再[1,24)的随机数)
  133.                         food.y = rand()%48 + 1;
  134.                         for(i=0 ; i<=snake.length - 1 ; i++)//如果食物的随机位置在蛇身位置重新随机一个食物位置
  135.                         {
  136.                                 if(food.x==snake.x[i] && food.y==snake.y[i])
  137.                                 {
  138.                                         break;
  139.                                 }
  140.                                 if(i == snake.length - 1)
  141.                                 {
  142.                                         i = snake.length;
  143.                                 }
  144.                         }
  145.                         if(i == snake.length + 1)//直到食物位置不在蛇身位置退出循环
  146.                         {
  147.                                 break;
  148.                         }
  149.                 }
  150.                 gotoxy(food.x, food.y);//光标移动到食物的位置
  151.                 printf("o"); //我用的“o”表示食物,也可以用其他字符表示
  152.         }
  153. }

  154. void get_speed(void)
  155. {
  156.         if(snake.length < 5)
  157.         {
  158.                 snake.speed = 300;
  159.         }
  160.         else if(snake.length < 10)
  161.         {
  162.                 snake.speed = 250;
  163.         }
  164.         else if(snake.length < 15)
  165.         {
  166.                 snake.speed = 200;
  167.         }
  168.         else if(snake.length < 20)
  169.         {
  170.                 snake.speed = 150;
  171.         }
  172.         else
  173.         {
  174.                 snake.speed = 100;
  175.         }
  176. }

  177. void move_snake(void)
  178. {
  179.         void gotoxy(int x, int y);

  180.         temp_x = snake.x[0];
  181.         temp_y = snake.y[0];//暂时把蛇头snake[0]的坐标保存再temp中
  182.         if(kbhit())//kbhit()详细说明自行百度,这里作用是如果键盘输入了字符就判断为真
  183.         {
  184.                 tempch = getch();//读入键盘输入的字符
  185.                 if(tempch == 'w' || tempch == 's' || tempch == 'a' || tempch == 'd')
  186.                 {
  187.                         ch = tempch;
  188.                 }
  189.         }
  190.         switch(ch)//只移动蛇头,并不是移动整个蛇身
  191.         {
  192.         case 'w' : snake.x[0] = snake.x[0] - 1;break;
  193.         case 's' : snake.x[0] = snake.x[0] + 1;break;
  194.         case 'a' : snake.y[0] = snake.y[0] - 1;break;
  195.         case 'd' : snake.y[0] = snake.y[0] + 1;break;
  196.         }
  197.         if(food.x == snake.x[0] && food.y == snake.y[0])//如果吃到食物,蛇身+1,分数+1
  198.         {
  199.                 snake.length = snake.length +1;
  200.                 score++;
  201.                 gotoxy(9, 69);
  202.                 printf("%d", score);
  203.         }
  204.         for(i=snake.length ; i>=2 ; i--)//从未来吃到食物的一节蛇的身体开始,把前一节的身体坐标赋给当前这节,以达到蛇的移动
  205.         {                               //第二节身体还保持原样, 因为蛇头的位置变动了
  206.                 snake.x[i] = snake.x[i-1];
  207.                 snake.y[i] = snake.y[i-1];
  208.         }
  209.         snake.x[1] = temp_x;
  210.         snake.y[1] = temp_y;//把蛇头移动前的坐标赋给第二节身体
  211.         gotoxy(snake.x[0], snake.y[0]);
  212.         printf("*");//打印蛇头
  213.         gotoxy(snake.x[snake.length], snake.y[snake.length]);
  214.         printf(" ");//清除“*”未来吃到食物的一节蛇的身体(即移动前,蛇的最后一节身体),不懂的话可以单步调试(我语文学的不太好。。。)
  215. }

  216. int if_dead(void)
  217. {
  218.         for(i=1 ; i<=snake.length-1 ; i++)//蛇头的坐标与蛇身体任意一节的坐标相同的话判断死亡
  219.         {
  220.                 if((snake.x[0] == snake.x[i] && snake.y[0] == snake.y[i]))
  221.                 {
  222.                         return 1;
  223.                 }
  224.         }
  225.         if((snake.x[0] == 0 || snake.x[0] == 24) || (snake.y[0] == 0 || snake.y[0] == 49))
  226.         {                     //蛇头的坐标与边界的坐标一样的话判断死亡
  227.                 return 1;
  228.         }
  229.         return 0;
  230. }

  231. void end(void)
  232. {
  233.         void gotoxy(int x, int y);

  234.         gotoxy(snake.x[0], snake.y[0]);
  235.         printf("+");
  236.         gotoxy(food.x, food.y);
  237.         printf(" ");
  238.         for(i=1 ; i<=snake.length-1 ; i++)
  239.         {
  240.                 gotoxy(snake.x[i], snake.y[i]);
  241.                 printf(" ");
  242.         }//清除蛇和食物
  243.         gotoxy(12, 20);
  244.         printf("游戏结束!");
  245. }

  246. void gotoxy(int x, int y) //这个函数作用是把屏幕坐标化,详细说明请自行百度
  247. {
  248.         HANDLE hout;
  249.         COORD cor;
  250.         hout=GetStdHandle(STD_OUTPUT_HANDLE);
  251.         cor.X=y;
  252.         cor.Y=x;
  253.         SetConsoleCursorPosition(hout,cor);
  254. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2018-5-4 22:15:25 | 显示全部楼层
亲~,这么多行代码,请问您这是什么语言?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-5-4 22:34:27 | 显示全部楼层
13572044595 发表于 2018-5-4 22:15
亲~,这么多行代码,请问您这是什么语言?

C语言啊0- 0
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-5-4 23:25:06 | 显示全部楼层
可以的,加油,我得向楼主看起,其实这个程序感觉就是C语言的面向对象编程了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-5-5 11:29:03 | 显示全部楼层
溯影 发表于 2018-5-4 23:25
可以的,加油,我得向楼主看起,其实这个程序感觉就是C语言的面向对象编程了

谢谢
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-5-7 22:07:41 From FishC Mobile | 显示全部楼层
真厉害!我已经从入门到放弃了。看来还得加油学习啊
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-5-8 17:52:33 | 显示全部楼层
弄过去全是繁体中文
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-5-8 17:59:56 | 显示全部楼层
不过我还是凭借我的聪明机智猜到怎么玩了,厉害了我的哥
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-5-8 19:03:07 | 显示全部楼层
厉害
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2018-5-8 19:03:08 | 显示全部楼层
魔法虫虫 发表于 2018-5-8 17:59
不过我还是凭借我的聪明机智猜到怎么玩了,厉害了我的哥

谢谢夸哦
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-5-8 19:03:44 | 显示全部楼层
鱼头骨 发表于 2018-5-7 22:07
真厉害!我已经从入门到放弃了。看来还得加油学习啊

嗯嗯,一起加油
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-5-31 00:14:04 | 显示全部楼层
楼主学了多久啊
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-5-31 00:14:34 | 显示全部楼层
楼主学习了多久啊。。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-8-2 12:23

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表