#includeint main() { initscr();//ncurse 界面的初始化函数 printw("This is curses windown");//在ncurse模式下的printf getch();//等待用户输入,如果没有这句话,程序就退出了,看不到运行的结果,也就是看不到上面那句话 endwin();//程序退出,调用改函数来恢复shell终端的显示,如果没有这句话,shell终端字乱码,坏掉 return 0; }
编译curses文件
gcc xxx.c -lcurses
ncurse的上下左右键
vi /usr/include/curses.h 可查看ncurse的宏定义
#define KEY_DOWN 0402 #define KEY_UP 0403 #define KEY_LEFT 0404 #define KEY_RIGHT 0405
验证代码
#include贪吃蛇小游戏参考代码int main() { int key; initscr(); keypad(stdscr,1);//设置了可以在stdscr中接受键盘的功能键(快捷键),1代表“是” while(1){ key = getch(); switch(key){ case KEY_DOWN: printw("DOWNn"); break; case KEY_UP: printw("UPn"); break; case KEY_LEFT: printw("LEFTn"); break; case KEY_RIGHT: printw("RIGHTn"); break; } } endwin(); return 0; }
此贪吃蛇小游戏的链表插入方式采用的是尾插法,*head 是贪吃蛇的头节点,也是贪吃蛇的尾巴。
#include#include #include #include #define UP 1 #define DOWN -1 #define LEFT 2 #define RIGHT -2 struct Snake{//贪吃蛇的每一个链表节点 int hang; int lie; struct Snake *next; }; struct Snake *head = NULL;//贪吃蛇的尾巴 struct Snake *tail = NULL;//贪吃蛇的头 struct Snake food;//贪吃蛇的食物 int key; int dir; void initNurses() { initscr();//ncurse 界面的初始化函数 keypad(stdscr,1);//设置了可以在stdscr中接受键盘的功能键(快捷键),1代表“是” } void initfood() { int x = rand()%19+1;//产生1~20的随机数 int y = rand()%20+1;//产生1~21的随机数 food.hang = x; food.lie = y; } int hasfood(int i, int j) { if(food.hang == i && food.lie == j){ return 1; } return 0; } int hasSnakeNode(int hang,int lie) { struct Snake *p; p = head; while(p != NULL){ if(p->hang==hang && p->lie == lie){ return 1; } p = p->next;//遍历贪吃蛇链表 } return 0; } void gamePic() { int hang;//定义地图位置行 int lie;//定义地图位置列 move(0,0);//当按下方向键时,让贪吃蛇往所按的方向键一直行走 for(hang=0; hang<=21; hang++){ for(lie=0; lie<=22; lie++){ if(hang==0 || hang==21){//地图第一行和最后一行为“--”墙 if(lie==0){ printw(" -"); }else if(lie==22){ printw("- "); }else{ printw("--"); } }else if(lie==0){//地图第一列和最后一列为“|”墙 printw(" |"); }else if(lie==22){ printw("| "); }else if(hasSnakeNode(hang,lie)){//打印贪吃蛇初始位置 printw("[]"); }else if(hasfood(hang,lie)){//打印贪吃蛇食物初始位置 printw("##"); }else{ printw(" "); } } printw("n"); } } void addNode()//通过尾插法增加链表节点 { struct Snake *new = (struct Snake*)malloc(sizeof(struct Snake)); new->lie = tail->lie+1; new->next = NULL; switch(dir){ case UP: //向上移动 new->hang = tail->hang-1; new->lie = tail->lie; break; case RIGHT: //向右移动 new->hang = tail->hang; new->lie = tail->lie+1; break; case LEFT: //向左移动 new->hang = tail->hang; new->lie = tail->lie-1; break; case DOWN: //向下移动 new->hang = tail->hang+1; new->lie = tail->lie; break; } tail->next = new; tail = new;//让新的节点成为链表尾节点 } void deleNode() { struct Snake *p; p = head; head = head->next;//让链表头指向下一个链表节点 free(p);//释放旧链表头的储存空间 } void initSnake() { struct Snake *p; dir = RIGHT;//默认向右行走 while(head != NULL){//贪吃蛇撞死后游戏重新开始时,释放旧的贪吃蛇节点的空间 p = head; head = head->next; free(p); } initfood();//贪吃蛇食物位置初始化 head = (struct Snake*)malloc(sizeof(struct Snake)); head->hang = 1; head->lie = 1;//贪吃蛇尾巴的初始位置 head->next = NULL; tail = head; addNode(); addNode(); addNode();//初始化后的贪吃蛇有4个节点 } int ifSnakeDie()//贪吃蛇撞死 { struct Snake *p; p = head; if(tail->hang == 0 || tail->lie == 0 || tail->hang == 21 || tail->lie == 22){ return 1;//撞墙死 } while(p->next != NULL){//撞自己尾巴死 if(p->hang == tail->hang && p->lie == tail->lie) return 1; p = p->next; } return 0; } void moveSnake() {//贪吃蛇每移动一个位置相等于链表尾插入一个节点,链表头节点删除 addNode();//通过尾插法增加链表节点 if(hasfood(tail->hang, tail->lie)){ initfood();//当贪吃蛇吃到食物时,重新创造食物 }else{//有吃到食物就跳过了删除节点,等于增加了一个节点,没吃到食物执行删除节点,实现贪吃蛇行走动态过程 deleNode();//删除头节点 } if(ifSnakeDie()){//如果贪吃蛇撞死,重新初始化贪吃蛇 initSnake(); } } void* refreshJieMian() { while(1){ usleep(150000);//时延要放在while的首行,不然游戏地图容易出现乱码,可调节贪吃蛇行走速度 moveSnake();//贪吃蛇行走函数定义 gamePic();//地图界面不断刷新 refresh();//刷新的界面在同一个位置出现 } } void turn(int diretion) {//贪吃蛇在往一个方向移动时,无法通过一次按键让它反向移动。例如贪吃蛇在往左方向移动时,无法通过一次按键向右移动。 if(abs(diretion) != abs(dir)){ dir = diretion; } } 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; } } } int main() { pthread_t t1; pthread_t t2; initNurses();//Nurses初始化 initSnake();//贪吃蛇初始化 gamePic();//贪吃蛇地图初始化 pthread_create(&t1, NULL, refreshJieMian, NULL);//创建线程1,让界面不断刷新 pthread_create(&t2, NULL, changeDir, NULL);//创建线程线程2,让贪吃蛇接受按键可以转向 while(1);//让进程不退出 endwin(); return 0; }



