实现前提是:
(1)Linux环境
(2)基于Ncurse图形库
涉及到的知识点有:
C语言基础,数据结构链表基础C变量,流程控制,函数,指针,结构体等
Linux系统编程文件编程,进程,线程,通信,第三方包等
使用ncurse的示例代码:
#include <curses.h> int main() { initscr();//ncurse界面的初始化函数 printw("This is a curses window.\n"); //在ncurse模式下的 printfgetch(); //等待用户输入,如果没有这句话,程序就退出了,看不到运行的结果,也就是看不到上面那句话 endwin(); //程序退出,调用改函数来恢复shell终端的显示,如果没有这句话,sheLl终端字乱码,坏掉 return 0; }
编译nucrse程序:
ncurse上下左右键值
贪吃蛇身子节点代码示例:(链表知识)
struct Snake { int row;//行坐标 int column;//列坐标 struct Snake *next;//下一个节点的位置 }
贪吃蛇全部代码:
#include <curses.h> #include <time.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> #define UP 1 #define DOWN -1 #define LEFT 2 #define RIGHT -2 struct Snake { int row; int column; struct Snake *next; }; struct Snake *head = NULL; struct Snake *tail = NULL; struct Snake food; int key; //方向键值。 int dir; //方向感应。 void initFood() { srand((unsigned)time(NULL)); int x = rand()%15+3; int y = rand()%15+3; food.row = x; food.column = y; } int allSnakeNode(int i,int j) { struct Snake *p = NULL; p = head; while(p != NULL){ if(p->row == i && p->column == j){ return 1; } p = p->next; } return 0; } int setFood(int i, int j) { if(food.row==i && food.column==j) { return 1; } return 0; } void gameMap() { int row; int column; move(0,0); for(row = 0;row < 20;row++){ if(row == 0){ for(column = 0;column < 20;column++){ printw("--"); } printw("\n"); } if(row >= 0 && row <= 19){ for(column = 0;column <= 20;column++){ if(column == 0 || column == 20){ printw("|"); }else if(allSnakeNode(row,column)){ printw("[]"); }else if(setFood(row,column)){ printw("##"); } else{ printw(" "); } } printw("\n"); } if(row == 19){ for(column = 0;column < 20;column++){ printw("--"); } printw("\n"); printw("Make by ZBB,key=%d,food.row=%d,food.column=%d\n",key,food.row,food.column); } } } void addNode() { struct Snake *new = (struct Snake *)malloc(sizeof(struct Snake)); new->next = NULL; switch(dir){ case UP: new->row = tail->row-1; new->column = tail->column; break; case DOWN: new->row = tail->row+1; new->column = tail->column; break; case LEFT: new->row = tail->row; new->column = tail->column-1; break; case RIGHT: new->row = tail->row; new->column = tail->column+1; break; } tail->next = new; tail = new; } void initSnake() { struct Snake *p = NULL; //贪吃蛇的初始方向:右。 dir = RIGHT; while(head != NULL){ p = head; head = head->next; free(p); } initFood(); //贪吃蛇的初始位置。 head = (struct Snake *)malloc(sizeof(struct Snake)); head->row = 3; head->column = 4; head->next = NULL; tail = head; //蛇的初始状态有五个节点。 addNode(); addNode(); addNode(); addNode(); } //移动过程中除了要增加节点,还要删除节点。 void deleteNode() { struct Snake *p = NULL; p = head; head = head->next; free(p); } int snakeDie() { struct Snake *p = NULL; p = head; if(tail->row < 0||tail->row == 20||tail->column == 0||tail->column == 20) { return 1; } while(p->next != NULL){ if(p->row == tail->row && p->column == tail->column){ return 1; } p = p->next; } return 0; } void moveSnake() { addNode(); if(setFood(tail->row,tail->column)){ initFood(); }else{ deleteNode(); } if(snakeDie()) { initSnake(); } } void* refreshWindow() { while(1) { moveSnake(); gameMap(); refresh(); usleep(105000); } } void turn(int direction) { if(abs(dir) != abs(direction)) { dir =direction; } } void* changeDir() { while(1) { key = getch(); switch(key) { //这四个为ncurses自带的表示方向的宏。 case KEY_DOWN: turn(DOWN); break; case KEY_UP: turn(UP); break; case KEY_LEFT: turn(LEFT); break; case KEY_RIGHT: turn(RIGHT); break; } } } int main() { pthread_t t1; pthread_t t2; //三行代码初始化游戏。 initscr(); keypad(stdscr,1); noecho(); initSnake(); gameMap(); pthread_create(&t1,NULL,refreshWindow,NULL); pthread_create(&t2,NULL,changeDir,NULL); while(1); getch(); endwin(); return 0; }
代码编译:
效果示例: