• 贪吃蛇游戏构建


    使用的编译器:DEV C++,VS code

    编译语言:C语言,JavaScript

     在知乎上看到的 RxJS 游戏之贪吃蛇,感觉很有趣,想自己动手试试。

    1. github上的源码 VS code的调试并不简单,会出现如下错误:

    (1)无法在PATH中找到node

    百度后的解决方案为:在node官网下载好nodejs,利用cmd命令处理程序验证环境变量Path中是否加入了nodejs的路径。

    具体方案参照:VS code调试nodejs,无法在PATH上找到运行时的node

    (2)找不到rxjs后续文件

    2.多次JavaScrip尝试无果后想试试C语言实现。

    转战DEV C++,用C语言实现起来还是挺简单的,难点在于:

    (1)输入为键盘的“上”“下”“左”“右”键,可通过switch语句来完成控制。

    (2)蛇的结构体定义初始化,游戏窗口设置,显示屏句柄变量定义需要扎实的C语言功底的。

    (3)蛇的移动控制,蛇和菜单的打印,蛇吃食物后的加速控制等。

    参考:C语言之贪吃蛇游戏源码

    下面附上C语言代码,可以自己试试:

    /**************************************************************************************************************
     **编写者:huangminqiang
     **编写日期:2010年9月8号
     **简要描述:贪吃蛇游戏,可加速,有颜色变化。
     **注:在DEV C++环境下能正常运行,印象中加速不太理想,敲键盘if(kbhit)可改为while(kbhit)。
     **************************************************************************************************************/

      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 start_game();
     30 void over_game();
     31 int main()
     32 {
     33  system("color 0D");  //设置文本为粉红色
     34  start_game();   //开始游戏
     35  over_game();   //结束游戏
     36 }
     37 /******光标移到指定位置**************************************************************/
     38 void gotoxy(HANDLE hOut, int x, int y)
     39 {
     40  COORD pos;
     41  pos.X = x;  //横坐标
     42  pos.Y = y;  //纵坐标
     43  SetConsoleCursorPosition(hOut, pos);
     44 }
     45 /******设置文本为绿色*****************************************************************/
     46 void Set_TextColor_Green (void)
     47 { 
     48  HANDLE Handle = GetStdHandle(STD_OUTPUT_HANDLE);
     49  
     50  SetConsoleTextAttribute(Handle, FOREGROUND_INTENSITY | FOREGROUND_GREEN);
     51 }
     52 /******制作游戏窗口******************************************************************/
     53 void make_frame()
     54 {
     55  HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);  //定义显示器句柄变量
     56  gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+13);  //打印选择菜单
     57  printf("Esc 退出游戏");
     58  gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+15);
     59  printf("长按方向键:加速");
     60  gotoxy(hOut,FrameX,FrameY);       //打印框角
     61  printf("");
     62  gotoxy(hOut,FrameX+2*Frame_width-2,FrameY);
     63  printf("");
     64  gotoxy(hOut,FrameX,FrameY+Frame_height);
     65  printf("");
     66  gotoxy(hOut,FrameX+2*Frame_width-2,FrameY+Frame_height);
     67  printf("");
     68  for(i=2;i<2*Frame_width-2;i+=2)
     69  {
     70   gotoxy(hOut,FrameX+i,FrameY);
     71   printf("");         //打印上横框
     72  }
     73  for(i=2;i<2*Frame_width-2;i+=2)
     74  {
     75   gotoxy(hOut,FrameX+i,FrameY+Frame_height);
     76   printf("");         //打印下横框
     77  }
     78  for(i=1;i<Frame_height;i++)
     79  {
     80   gotoxy(hOut,FrameX,FrameY+i); 
     81   printf("");         //打印左竖框
     82  }
     83  for(i=1;i<Frame_height;i++)
     84  {
     85   gotoxy(hOut,FrameX+2*Frame_width-2,FrameY+i); 
     86   printf("");         //打印右竖框
     87  }
     88  gotoxy(hOut,FrameX+Frame_width-5,FrameY-2);   //打印游戏名称 
     89  Set_TextColor_Green ();        //设置蛇为绿色
     90  printf("贪吃蛇游戏");
     91 }
     92 /******结束菜单*******************************************************************/
     93 void over_game()
     94 {
     95  system("cls");
     96  printf("\n\n\n\n\n\n\n\n\t\t\t\t游戏结束\n\n\n");
     97  Sleep(2000);
     98  getch();
     99 }
    100 /******菜单信息***************************************************************/
    101 void print_information(HANDLE hOut,struct Snake *snake,struct Food *food)
    102 {
    103  gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+1);
    104  printf("level : %d",snake->count/5+1);    //打印游戏等级
    105  gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+3);
    106  printf("score : %d",10*snake->count);    //打印游戏得分
    107  gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+5);
    108  printf("eat food : %d",snake->count);    //打印产生食物个数 
    109  gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+7);
    110  printf("speed : %dms",snake->speed);    //打印游戏速度
    111  gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+9);
    112  printf("foodX : %d",food->x);      //打印食物的横坐标
    113  gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+11);
    114  printf("foodY : %d",food->y);      //打印食物的竖坐标
    115 }
    116 /******初始化蛇**********************************************************************/
    117 void init_snake(struct Snake *snake)
    118 {
    119  snake->x[0]=FrameX+2;     //初始化蛇的横坐标 
    120  snake->y[0]=FrameY+Frame_height/2;  //初始化蛇的竖坐标 
    121  snake->speed=300;      //初始化蛇的速度为300ms
    122  snake->length=3;      //初始化蛇的长度为3节
    123  snake->count=0;       //初始化蛇吃的个数为0
    124  for(i=1;i<snake->length;i++)
    125  {/* 依次得到蛇身、蛇头的坐标 */
    126   snake->x[i]=snake->x[i-1]+2;
    127   snake->y[i]=snake->y[i-1];
    128  } 
    129 }
    130 /******移动蛇*************************************************************************/
    131 void move_snake(HANDLE hOut,struct Snake *snake)
    132 {
    133  gotoxy(hOut,snake->x[0],snake->y[0]);
    134  printf("  ");       /* 清除蛇尾*/
    135  for(i=1;i<snake->length;i++)
    136  {/* 后一节的坐标依次取代前一节的坐标 */
    137   snake->x[i-1]=snake->x[i];
    138   snake->y[i-1]=snake->y[i];
    139  }
    140 }
    141 /******打印蛇*************************************************************************/
    142 void print_snake(HANDLE hOut,struct Snake *snake)
    143 {
    144  for(i=0;i<snake->length;i++)
    145  {
    146   gotoxy(hOut,snake->x[i],snake->y[i]);
    147   if(i==0)
    148   {
    149    printf("");       //打印蛇尾
    150   }
    151   else if(i==snake->length-1)
    152   {
    153    printf("¤");       //打印蛇头
    154   }
    155   else
    156   {
    157    printf("");       //打印蛇身
    158   }
    159  }
    160 }
    161 /******随机产生食物*******************************************************************/
    162 void get_food(HANDLE hOut,struct Snake *snake,struct Food *food)
    163 {
    164  srand((unsigned)time(NULL));       //初始化随机数
    165  while(1)
    166  {/* 产生食物的条件:1.在游戏窗口内 2.不在蛇的身上 */ 
    167   food->x = rand() % (Frame_width-1);
    168   food->y = rand() % Frame_height;
    169   if( food->x==0 || food->y==0 )
    170   {
    171    continue;
    172   }
    173   food->x = 2*food->x + FrameX;      //得到食物的横坐标
    174   food->y+=FrameY;         //得到食物的竖坐标
    175   for(i=0;i<snake->length;i++)
    176   {/* 判断食物是否在蛇的身上,如果在蛇身上,则重新产生;否则,打印蛇身 */
    177    if( food->x==snake->x[i] && food->y==snake->y[i] )
    178    {
    179     break;
    180    }
    181   }
    182   if(i==snake->length)
    183   {
    184    gotoxy(hOut,food->x,food->y);
    185    printf("");
    186    break;
    187   } 
    188  }
    189 }
    190 /******吃食物***************************************************************************/
    191 void eat_food(HANDLE hOut,struct Snake *snake,struct Food *food)
    192 {
    193  if( snake->x[snake->length-1]==food->x && snake->y[snake->length-1]==food->y )
    194  {/* 如果蛇头位置与食物位置相同,吃食物 */
    195   snake->length++;      //吃一个食物,蛇身增长一节
    196   for(i=snake->length-1;i>=1;i--)
    197   {/* 蛇后节坐标依次赋值给蛇前一节的坐标,依次得到蛇身及蛇头的坐标 */
    198    snake->x[i]=snake->x[i-1];
    199    snake->y[i]=snake->y[i-1];
    200   } 
    201   snake->x[0]=a[0];      //得到蛇尾移动前的横坐标
    202   snake->y[0]=a[1];      //得到蛇尾移动前的竖坐标  
    203   get_food(hOut,snake,food);    //重新产生食物
    204   snake->count++;       //食物的个数增1
    205   if( snake->count%5==0 )
    206   {/* 当蛇吃Up_level个食物时,速度加快Up_speed毫秒并且升一级 */
    207    snake->speed-=50;
    208   }
    209  }
    210 }
    211 /******穿墙**********************************************************************************/
    212 void through_wall(HANDLE hOut,struct Snake *snake,char ch)
    213 {
    214  if( ch==72 && snake->y[snake->length-1]==FrameY)
    215  {
    216   snake->y[snake->length-1] = FrameY+Frame_height-1; //如果蛇在上框且向上移动,穿墙
    217  }
    218  if( ch==80 && snake->y[snake->length-1]==FrameY+Frame_height )
    219  {
    220   snake->y[snake->length-1] = FrameY+1;    //如果蛇在下框且向下移动,穿墙
    221  }
    222  if( ch==75 && snake->x[snake->length-1]==FrameX )
    223  {
    224   snake->x[snake->length-1] = FrameX+2*Frame_width-4; //如果蛇在左框且向左移动,穿墙
    225  }
    226  if( ch==77 && snake->x[snake->length-1]==FrameX+2*Frame_width-2 )
    227  {
    228   snake->x[snake->length-1] = FrameX+2;    //如果蛇在右框且向右移动,穿墙
    229  }
    230 }
    231 /******判断蛇是否死**************************************************************************/
    232 int if_die(struct Snake *snake)
    233 {/* 当蛇头碰到自身时,蛇死 ,返回值为0 */
    234  for(i=0;i<snake->length-1;i++)
    235  {
    236   if( snake->x[snake->length-1]==snake->x[i] && snake->y[snake->length-1]==snake->y[i] )
    237   {
    238    return 0;
    239   }
    240  }
    241  return 1;
    242 }
    243 /******开始游戏*******************************************************************************/
    244 void start_game()
    245 {
    246  unsigned char ch=77;        //定义用于接收键盘输入的字符变量
    247  HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); //定义显示器句柄变量
    248  struct Snake s,*snake=&s;      //定义蛇的结构体指针并指向蛇的结构体
    249  struct Food f,*food=&f;       //定义食物的结构体指针并指向食物的结构体
    250  
    251  make_frame();         //制作游戏窗口 
    252  init_snake(snake);        //初始化蛇
    253  get_food(hOut,snake,food);      //随机产生食物
    254  while(1)
    255  {
    256   print_information(hOut,snake,food);   //打印菜单信息
    257   a[0]=snake->x[0];       //记住蛇尾的横坐标
    258   a[1]=snake->y[0];       //记住蛇尾的竖坐标
    259   j=0;
    260   if(kbhit())
    261   {/* 判断是否按下键盘,如果按下,ch接收键盘输入 */
    262    ch=getch();
    263    if(kbhit())
    264    {/* 如果长按键盘,则加速 */
    265     Sleep(20);
    266     j=1;
    267    }
    268   }
    269   switch(ch)
    270   {
    271    case 72:
    272     {/* 向上移动 */
    273      move_snake(hOut,snake);   //移动蛇
    274      snake->y[snake->length-1]-=1; //蛇头的竖坐标向上移,即减1 
    275      break;
    276     }
    277    case 80:
    278     {/* 向下移动 */
    279      move_snake(hOut,snake);   //移动蛇
    280      snake->y[snake->length-1]+=1; //蛇头的竖坐标向下移,即加1
    281      break;
    282     }
    283    case 75:
    284     {/* 向左移动 */
    285      move_snake(hOut,snake);   //移动蛇
    286      snake->x[snake->length-1]-=2; //蛇头的横坐标向左移,即减2
    287      break;
    288     }    
    289    case 77:
    290     {/* 向右移动 */
    291      move_snake(hOut,snake);   //移动蛇
    292      snake->x[snake->length-1]+=2; //蛇头的横坐标向右移,即加2
    293      break;
    294     }
    295   }
    296   through_wall(hOut,snake,ch);    //穿墙   
    297   eat_food(hOut,snake,food);     //吃食物
    298   print_snake(hOut,snake);     //打印蛇
    299   if( if_die(snake)==0 || ch==27 || snake->speed==50 )
    300   {/* 游戏结束条件:1.蛇碰到自身 2.按Esc键 3.速度为50ms */
    301    gotoxy(hOut,FrameX+Frame_width-2,FrameY+Frame_height/2-1);
    302    printf("Game Over");
    303    Sleep(2000);
    304    break;
    305   }
    306   if(j==0)
    307   {
    308    Sleep(snake->speed);      //延迟时间
    309   }
    310   else
    311   {
    312    Sleep(10);
    313   } 
    314  }
    315 }

     运行结果:

    3.还会努力尝试用VS Code编译器来实现,在这之前先把编译器使用熟练,会编译运行,了解它的操作。

  • 相关阅读:
    数据库
    HTTP请求(Request)和回应(Response)对象
    [Uliweb]-URL映射
    git生成Key操作保存到GITHUB中
    SQL中char、varchar、nvarchar的区别
    Uliweb之 ORM基本使用(Sqlalchemy)
    ORM查询
    CentOS更改ssh端口
    django static文件的引入方式
    Redis持久化策略(RDB &AOF)
  • 原文地址:https://www.cnblogs.com/BoBoRing/p/8883473.html
Copyright © 2020-2023  润新知