如何使用ncurse
#include <curses.h>
int main()
{
initscr();//ncurse 界面的初始化函数
printw("This is curses window\n");//在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 <curses.h>
int main()
{
int key;
initscr();
keypad(stdscr,1);//设置了可以在stdscr中接受键盘的功能键(快捷键),1代表“是”
while(1){
key = getch();
switch(key){
case KEY_DOWN:
printw("DOWN\n");
break;
case KEY_UP:
printw("UP\n");
break;
case KEY_LEFT:
printw("LEFT\n");
break;
case KEY_RIGHT:
printw("RIGHT\n");
break;
}
}
endwin();
return 0;
}
贪吃蛇小游戏参考代码
此贪吃蛇小游戏的链表插入方式采用的是尾插法,*head
是贪吃蛇的头节点,也是贪吃蛇的尾巴。
#include <ncurses.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 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;
}
演示视频
7.46 Vlc:/ 终于把程序写完了,玩贪吃蛇吗? https://v.douyin.com/NkWJmoD/ 复制此链接,打开Dou音搜索,直接观看视频!