找回密码
 注册

QQ登录

只需一步,快速开始

搜索

C语言 贪吃蛇程序代码与运行界面展示

[复制链接]
coolice 发表于 2020-5-3 18:13:54 | 显示全部楼层 |阅读模式
224011wynu9t7lj9rfuefu.png

  1. #include <stdio.h>
  2. #include <windows.h>
  3. #include <conio.h>
  4. #include <time.h>
  5. //游戏窗口
  6. #define FrameX 4   //游戏窗口左上角的X轴坐标
  7. #define FrameY 4   //游戏窗口左上角的Y轴坐标
  8. #define Frame_height  20 //游戏窗口的高度
  9. #define Frame_width   20 //游戏窗口的宽度
  10. //定义全局变量
  11. int i,j;
  12. int a[2];     //用于记住蛇尾坐标,其中a[0]、a[1]分别表示横、竖坐标
  13. //声明蛇的结构体
  14. struct Snake
  15. {
  16. int x[100];    //蛇的横坐标,其中x[0]表示蛇尾的横坐标,x[N-1]表示蛇头的横坐标
  17. int y[100];    //蛇的竖坐标,其中y[0]表示蛇尾的竖坐标,y[N-1]表示蛇头的竖坐标
  18. int count;    //蛇吃食物的个数
  19. int length;    //蛇的长度
  20. int speed;    //蛇的速度
  21. };
  22. //声明食物的结构体
  23. struct Food
  24. {
  25. int x;     //食物的横坐标
  26. int y;     //食物的竖坐标
  27. };


  28. /******光标移到指定位置**************************************************************/
  29. void gotoxy(HANDLE hOut, int x, int y)
  30. {
  31. COORD pos;
  32. pos.X = x;  //横坐标
  33. pos.Y = y;  //纵坐标
  34. SetConsoleCursorPosition(hOut, pos);
  35. }
  36. /******设置文本为绿色*****************************************************************/
  37. void Set_TextColor_Green (void)
  38. {
  39. HANDLE Handle = GetStdHandle(STD_OUTPUT_HANDLE);

  40. SetConsoleTextAttribute(Handle, FOREGROUND_INTENSITY | FOREGROUND_GREEN);
  41. }
  42. /******制作游戏窗口******************************************************************/
  43. void make_frame()
  44. {
  45. HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);  //定义显示器句柄变量
  46. gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+13);  //打印选择菜单
  47. printf("Esc 退出游戏");
  48. gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+15);
  49. printf("长按方向键:加速");
  50. gotoxy(hOut,FrameX,FrameY);       //打印框角
  51. printf("╔");
  52. gotoxy(hOut,FrameX+2*Frame_width-2,FrameY);
  53. printf("╗");
  54. gotoxy(hOut,FrameX,FrameY+Frame_height);
  55. printf("╚");
  56. gotoxy(hOut,FrameX+2*Frame_width-2,FrameY+Frame_height);
  57. printf("╝");
  58. for(i=2;i<2*Frame_width-2;i+=2)
  59. {
  60.   gotoxy(hOut,FrameX+i,FrameY);
  61.   printf("═");         //打印上横框
  62. }
  63. for(i=2;i<2*Frame_width-2;i+=2)
  64. {
  65.   gotoxy(hOut,FrameX+i,FrameY+Frame_height);
  66.   printf("═");         //打印下横框
  67. }
  68. for(i=1;i<Frame_height;i++)
  69. {
  70.   gotoxy(hOut,FrameX,FrameY+i);
  71.   printf("║");         //打印左竖框
  72. }
  73. for(i=1;i<Frame_height;i++)
  74. {
  75.   gotoxy(hOut,FrameX+2*Frame_width-2,FrameY+i);
  76.   printf("║");         //打印右竖框
  77. }
  78. gotoxy(hOut,FrameX+Frame_width-5,FrameY-2);   //打印游戏名称
  79. Set_TextColor_Green ();        //设置蛇为绿色
  80. printf("贪吃蛇游戏");
  81. }
  82. /******结束菜单*******************************************************************/
  83. void over_game()
  84. {
  85. system("cls");
  86. printf("\n\n\n\n\n\n\n\n\t\t\t\t游戏结束\n\n\n");
  87. Sleep(2000);
  88. getch();
  89. }
  90. /******菜单信息***************************************************************/
  91. void print_information(HANDLE hOut,struct Snake *snake,struct Food *food)
  92. {
  93. gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+1);
  94. printf("level : %d",snake->count/5+1);    //打印游戏等级
  95. gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+3);
  96. printf("score : %d",10*snake->count);    //打印游戏得分
  97. gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+5);
  98. printf("eat food : %d",snake->count);    //打印产生食物个数
  99. gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+7);
  100. printf("speed : %dms",snake->speed);    //打印游戏速度
  101. gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+9);
  102. printf("foodX : %d",food->x);      //打印食物的横坐标
  103. gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+11);
  104. printf("foodY : %d",food->y);      //打印食物的竖坐标
  105. }
  106. /******初始化蛇**********************************************************************/
  107. void init_snake(struct Snake *snake)
  108. {
  109. snake->x[0]=FrameX+2;     //初始化蛇的横坐标
  110. snake->y[0]=FrameY+Frame_height/2;  //初始化蛇的竖坐标
  111. snake->speed=300;      //初始化蛇的速度为300ms
  112. snake->length=3;      //初始化蛇的长度为3节
  113. snake->count=0;       //初始化蛇吃的个数为0
  114. for(i=1;i<snake->length;i++)
  115. {/* 依次得到蛇身、蛇头的坐标 */
  116.   snake->x[i]=snake->x[i-1]+2;
  117.   snake->y[i]=snake->y[i-1];
  118. }
  119. }
  120. /******移动蛇*************************************************************************/
  121. void move_snake(HANDLE hOut,struct Snake *snake)
  122. {
  123. gotoxy(hOut,snake->x[0],snake->y[0]);
  124. printf("  ");       /* 清除蛇尾*/
  125. for(i=1;i<snake->length;i++)
  126. {/* 后一节的坐标依次取代前一节的坐标 */
  127.   snake->x[i-1]=snake->x[i];
  128.   snake->y[i-1]=snake->y[i];
  129. }
  130. }
  131. /******打印蛇*************************************************************************/
  132. void print_snake(HANDLE hOut,struct Snake *snake)
  133. {
  134. for(i=0;i<snake->length;i++)
  135. {
  136.   gotoxy(hOut,snake->x[i],snake->y[i]);
  137.   if(i==0)
  138.   {
  139.    printf("○");       //打印蛇尾
  140.   }
  141.   else if(i==snake->length-1)
  142.   {
  143.    printf("¤");       //打印蛇头
  144.   }
  145.   else
  146.   {
  147.    printf("⊙");       //打印蛇身
  148.   }
  149. }
  150. }
  151. /******随机产生食物*******************************************************************/
  152. void get_food(HANDLE hOut,struct Snake *snake,struct Food *food)
  153. {
  154. srand((unsigned)time(NULL));       //初始化随机数
  155. while(1)
  156. {/* 产生食物的条件:1.在游戏窗口内 2.不在蛇的身上 */
  157.   food->x = rand() % (Frame_width-1);
  158.   food->y = rand() % Frame_height;
  159.   if( food->x==0 || food->y==0 )
  160.   {
  161.    continue;
  162.   }
  163.   food->x = 2*food->x + FrameX;      //得到食物的横坐标
  164.   food->y+=FrameY;         //得到食物的竖坐标
  165.   for(i=0;i<snake->length;i++)
  166.   {/* 判断食物是否在蛇的身上,如果在蛇身上,则重新产生;否则,打印蛇身 */
  167.    if( food->x==snake->x[i] && food->y==snake->y[i] )
  168.    {
  169.     break;
  170.    }
  171.   }
  172.   if(i==snake->length)
  173.   {
  174.    gotoxy(hOut,food->x,food->y);
  175.    printf("⊙");
  176.    break;
  177.   }
  178. }
  179. }
  180. /******吃食物***************************************************************************/
  181. void eat_food(HANDLE hOut,struct Snake *snake,struct Food *food)
  182. {
  183. if( snake->x[snake->length-1]==food->x && snake->y[snake->length-1]==food->y )
  184. {/* 如果蛇头位置与食物位置相同,吃食物 */
  185.   snake->length++;      //吃一个食物,蛇身增长一节
  186.   for(i=snake->length-1;i>=1;i--)
  187.   {/* 蛇后节坐标依次赋值给蛇前一节的坐标,依次得到蛇身及蛇头的坐标 */
  188.    snake->x[i]=snake->x[i-1];
  189.    snake->y[i]=snake->y[i-1];
  190.   }
  191.   snake->x[0]=a[0];      //得到蛇尾移动前的横坐标
  192.   snake->y[0]=a[1];      //得到蛇尾移动前的竖坐标  
  193.   get_food(hOut,snake,food);    //重新产生食物
  194.   snake->count++;       //食物的个数增1
  195.   if( snake->count%5==0 )
  196.   {/* 当蛇吃Up_level个食物时,速度加快Up_speed毫秒并且升一级 */
  197.    snake->speed-=50;
  198.   }
  199. }
  200. }
  201. /******穿墙**********************************************************************************/
  202. void through_wall(HANDLE hOut,struct Snake *snake,char ch)
  203. {
  204. if( ch==72 && snake->y[snake->length-1]==FrameY)
  205. {
  206.   snake->y[snake->length-1] = FrameY+Frame_height-1; //如果蛇在上框且向上移动,穿墙
  207. }
  208. if( ch==80 && snake->y[snake->length-1]==FrameY+Frame_height )
  209. {
  210.   snake->y[snake->length-1] = FrameY+1;    //如果蛇在下框且向下移动,穿墙
  211. }
  212. if( ch==75 && snake->x[snake->length-1]==FrameX )
  213. {
  214.   snake->x[snake->length-1] = FrameX+2*Frame_width-4; //如果蛇在左框且向左移动,穿墙
  215. }
  216. if( ch==77 && snake->x[snake->length-1]==FrameX+2*Frame_width-2 )
  217. {
  218.   snake->x[snake->length-1] = FrameX+2;    //如果蛇在右框且向右移动,穿墙
  219. }
  220. }
  221. /******判断蛇是否死**************************************************************************/
  222. int if_die(struct Snake *snake)
  223. {/* 当蛇头碰到自身时,蛇死 ,返回值为0 */
  224. for(i=0;i<snake->length-1;i++)
  225. {
  226.   if( snake->x[snake->length-1]==snake->x[i] && snake->y[snake->length-1]==snake->y[i] )
  227.   {
  228.    return 0;
  229.   }
  230. }
  231. return 1;
  232. }
  233. /******开始游戏*******************************************************************************/
  234. void start_game()
  235. {
  236. unsigned char ch=77;        //定义用于接收键盘输入的字符变量
  237. HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); //定义显示器句柄变量
  238. struct Snake s,*snake=&s;      //定义蛇的结构体指针并指向蛇的结构体
  239. struct Food f,*food=&f;       //定义食物的结构体指针并指向食物的结构体

  240. make_frame();         //制作游戏窗口
  241. init_snake(snake);        //初始化蛇
  242. get_food(hOut,snake,food);      //随机产生食物
  243. while(1)
  244. {
  245.   print_information(hOut,snake,food);   //打印菜单信息
  246.   a[0]=snake->x[0];       //记住蛇尾的横坐标
  247.   a[1]=snake->y[0];       //记住蛇尾的竖坐标
  248.   j=0;
  249.   if(kbhit())
  250.   {/* 判断是否按下键盘,如果按下,ch接收键盘输入 */
  251.    ch=getch();
  252.    if(kbhit())
  253.    {/* 如果长按键盘,则加速 */
  254.     Sleep(20);
  255.     j=1;
  256.    }
  257.   }
  258.   switch(ch)
  259.   {
  260.    case 72:
  261.     {/* 向上移动 */
  262.      move_snake(hOut,snake);   //移动蛇
  263.      snake->y[snake->length-1]-=1; //蛇头的竖坐标向上移,即减1
  264.      break;
  265.     }
  266.    case 80:
  267.     {/* 向下移动 */
  268.      move_snake(hOut,snake);   //移动蛇
  269.      snake->y[snake->length-1]+=1; //蛇头的竖坐标向下移,即加1
  270.      break;
  271.     }
  272.    case 75:
  273.     {/* 向左移动 */
  274.      move_snake(hOut,snake);   //移动蛇
  275.      snake->x[snake->length-1]-=2; //蛇头的横坐标向左移,即减2
  276.      break;
  277.     }   
  278.    case 77:
  279.     {/* 向右移动 */
  280.      move_snake(hOut,snake);   //移动蛇
  281.      snake->x[snake->length-1]+=2; //蛇头的横坐标向右移,即加2
  282.      break;
  283.     }
  284.   }
  285.   through_wall(hOut,snake,ch);    //穿墙   
  286.   eat_food(hOut,snake,food);     //吃食物
  287.   print_snake(hOut,snake);     //打印蛇
  288.   if( if_die(snake)==0 || ch==27 || snake->speed==50 )
  289.   {/* 游戏结束条件:1.蛇碰到自身 2.按Esc键 3.速度为50ms */
  290.    gotoxy(hOut,FrameX+Frame_width-2,FrameY+Frame_height/2-1);
  291.    printf("Game Over");
  292.    Sleep(2000);
  293.    break;
  294.   }
  295.   if(j==0)
  296.   {
  297.    Sleep(snake->speed);      //延迟时间
  298.   }
  299.   else
  300.   {
  301.    Sleep(10);
  302.   }
  303. }
  304. }
  305. void main()
  306. {
  307. system("color 0D");  //设置文本为粉红色
  308. start_game();   //开始游戏
  309. over_game();   //结束游戏
  310. }
复制代码


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

本版积分规则

QQ|手机版|小黑屋|ELEOK |网站地图

GMT+8, 2024-4-27 05:57

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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