在linux下用C语言编写贪吃蛇小游戏

利用链表和结构体来编写贪吃蛇小游戏,这边还会用点线程,分别有以下模块:
1、地图规划
2、蛇身体的初始化
3、蛇的方向移动
4、食物的初始化和随机出现
5、蛇撞墙和咬自己的尾巴

地图规划

我们在设计地图的时候,需要用到ncurses,头文件 #include

ncurses(new curses)是一个程序库,它提供了API,可以允许程序员编写独立于终端的基于文本的用户界面。它是一个虚拟终端中的“类GUI”应用软件工具箱。它还优化了屏幕刷新方法,以减少使用远程shell时遇到的延迟。我们需要在虚拟机中装以下ncurses库

sudo apt-get install libncurses5-dev
sudo apt-get install ncurses-doc//这是ncurses的文件内容 可以查看ncurse的函数说明
man endwin//查看endwin函数的说明

使用ncurses的主要语句:

 initscr(); //使用ncurses首先要初始化一下
 printw("hello");//输出语句
 getch();//等待用户输入
 endwin();//结束并退出ncurses
 move(y,x); // 将光标移动至(x,y)处。
 refresh() ; //经过refresh()函数刷新之后才能够显示到屏幕上。

设计一个20x20的地图,我们可以使用两个for循环输出我们的行和列

void gamepic(){ //地图规划
	int col;//lie
	int row;//行
	for (row = 0; row < 20; row++) {
        if (row == 0) {
             for (col = 0; col < 20; col++) {
                printw("--");
            }
        }
         printw("\n");
         for (col = 0; col <= 20; col++) {
             if (col == 0 || col == 20) {
               	 printw("|");
             } else{
             	printw("  ");
			}
             if (row == 19) {
            		printw("\n");
             for (col = 0; col < 20; col++) {
        		  	printw("--");
             }
        }
     }
  }

在linux下用C语言编写贪吃蛇小游戏_第1张图片

2、蛇身体的初始化

这边对蛇身体的构造,我们用链表和结构体来完成身体的构造,结构体内包含行和列、下一个节点指针。通过坐标的形式显示我们蛇的身子

 struct Snake {
      int row;
      int col;
    struct Snake *next;
 };
 struct Snake *head = NULL;
  struct Snake *tail = NULL;  //这时我们将链表的头结点和尾指针设定为全局变量
void initSnake() { //蛇身体的初始化
     struct Snake *p;
    while (head != NULL) {  
         p = head;
         head = head->next;
         free(p);
    }   
      head = (struct Snake *)malloc(sizeof(struct Snake));
     head->row = 2;
     head->col = 2;
     head->next = NULL;    
     tail = head; 
    addNode();  //添加蛇的身子
    addNode();
 }   
 void addNode(){
		strcut Snake *new=(struct Snake *)malloc(sizeof(struct Snake));
		new->next=NULL;
		tail->next=new; //添加节点
		tail=new;
}

链表创建完毕,现在来显示蛇的身体,这时我们可以通过一个指针对链表进行遍历,如果此时指针所指的行和列符合地图上的行和列,显示蛇的身子。

 int Snake_body(int i, int j) { //对蛇的身体链表进行遍历 跟地图的行和列比较,相同返回1,不同返回0
     struct Snake *p;
     p = head;
     while (p != NULL) {
        if (p->row == i && p->col == j) {
            return 1;
         } 
        p = p->next;
     }       
    return 0;
 } 
 //对地图规划的函数进行修改
  for (col = 0; col <= 20; col++) {
             if (col == 0 || col == 20) {
                printw("|");
             } else if (Snake_body(row, col)) { //显示蛇的身体
                printw("[]");
            }  else {
                printw("  ");
            }
      }

在linux下用C语言编写贪吃蛇小游戏_第2张图片

3、蛇方向的移动

那么蛇的方向移动是怎么回事呢,假如我们向右移动,就是将我们的链表在右边添加一个节点,然后将最左边的节点删除,再通过更新我们的地图,来达到移动的效果。所以我们要写一个删除节点的函数

void deleteNode() {
    struct Snake *p;
    p = head;
   head = head->next; //将头结点进行移动
    free(p);
 }
 void movesnake() { //蛇身子的移动
     addNode();    
     deleteNode();
 } 

在linux下用C语言编写贪吃蛇小游戏_第3张图片
那么如何让蛇一直动起来呢,这时候我们可以利用ncurses的refresh函数,它有刷新屏幕的功能

 void refreshJieMian() {
     while (1) {
         movesnake();
         gamepic();
         refresh();
        usleep(100000); //延迟1ms
    }   
} 

接下来我们要实现通过按键来实现蛇方向的移动,在ncurese中有可以获得上下左右键的值

keypad(stdscr, 1); //将这句话加入initNcurses函数中,意思是从键盘获取上下左右的值
int dir;//设置变量dir为全局变量
 #define UP 1
  #define DOWN -1
  #define LEFT 2
  #define RIGHT -2

 void turn(int direction) {
    if (abs(dir) != abs(direction)) {  //以绝对值的方式让蛇单方向行走
         dir = direction; 
    }
 }

void changeDir() {    //从键盘中获取上下左右的信息
     while (1) {
         key = getch();
         switch (key) {
             case KEY_DOWN:
                 turn(DOWN);
                 break;
            case KEY_UP:
                 turn(UP);
                break;
             case KEY_LEFT:
                 turn(LEFT);
                 break;
            case KEY_RIGHT:
                turn(RIGHT);
                break;
     }       
   }   
 } 
switch (dir) { //上下左右的移动,将这段加入movesnake函数中
        case UP: //上
             new->row = tail->row - 1;
             new->col = tail->col;
             break;
        case DOWN: //下
             new->row = tail->row + 1;
             new->col = tail->col;
            break;
        case LEFT: //左
           new->row = tail->row;
            new->col = tail->col - 1;
             break;
       case RIGHT: //右
              new->row = tail->row;
              new->col = tail->col + 1;
             break;
   }

4、食物的初始化和随机出现

struct Snake food; //用蛇的结构体来定义一个食物

 void initfood() {
      int x = rand() % 20; //随机取值,因为地图是20x20的,要在这范围中出现,对20求余数
      int y = rand() % 20;
      food.row = x;
      food.col = y;
  } 
   int Snake_food(int i, int j) { //跟身子的显示道理一样 
      if (food.row == i && food.col == j) {
         return 1;
     }
    return 0;
 } 
 //对将食物的显示加入地图规划函数中
 for (col = 0; col <= 20; col++) {
             if (col == 0 || col == 20) {
                printw("|");
           } else if (Snake_body(row, col)) {
                printw("[]");
           } else if (Snake_food(row, col)) {
                printw("##");
           } else {
               printw("  ");
           }     
      } 

5、蛇撞墙和自杀

对链表的尾指针的值进行判断,超过地图的范围就将它初始化

 int ifsnakedie() {
    struct Snake *p;
     p = head;
     if (tail->row == -1 || tail->row == 20 || tail->col == 0 ||   //撞墙
       tail->col == 20) {
       return 1;
     }
     while (p->next != NULL) {
         if (p->row == tail->row && p->col == tail->col) {   //咬到自己的尾巴
             return 1;
        } 
        p = p->next;
    }       
    return 0;
 }
 //修改移动函数
 void movesnake() {
     addNode();
     if (Snake_food(tail->row, tail->col)) {   //if判断的作用,如果吃到食物就让身子边长,加一个节点,并重新显示食物的位置。没有吃到则不变
        initfood(); 
    } else {     
       deleteNode();
   } 
     if (ifsnakedie()) {
       initSnake();
   } 
 }   

贪吃蛇的具体功能函数已经完成,在最后我们可以将入线程来完成最后的步骤

//主函数 线程的头文件一定要加 #include 
 void main() {
    pthread_t t1;
     pthread_t t2;
     initNcurses();
     initSnake();
    gamepic();
     pthread_create(&t1, NULL, refreshJieMian, NULL); //在refreshJieMian函数名前记得要加*
     pthread_create(&t2, NULL, changeDir, NULL); //在changeDir函数名前记得要加*
   while (1) ;
     getch();
   endwin();
 }

在linux下用C语言编写贪吃蛇小游戏_第4张图片

你可能感兴趣的:(在linux下用C语言编写贪吃蛇小游戏)