达者为先  师者之意

基于Linux ncurses图形库的贪吃蛇小游戏

  • 前言
  • 1 ncurses库程序的标准模式
  • 2 ncurses库的常用函数
  • 3 基于Linux ncurses图形库的贪吃蛇小游戏的完整代码

前言

为什么要用到ncurses库呢?
因为直接用 scanf 和 getchar 时,需要按下回车才能完成输入;
而贪吃蛇小项目用方向控制小蛇时,不可能按下方向键后还要按下回车;
所以我们需要ncurses库来完成对方向键的输入。

若Ubuntu没有安装ncurses库,则需要安装
执行命令
sudo apt-get install libncurses5-dev
即可安装

如下图所示
没按下回车,用 scanf 不能输入方向键。

#include <stdio.h>
int main()
{printf("------------------------------------\n");
printf("|[][][]                            |\n");
printf("|                                  |\n");
printf("|                                  |\n");
printf("|                                  |\n");
printf("|                                  |\n");
printf("|                                  |\n");
printf("|                                  |\n");
printf("|                                  |\n");
printf("|                                  |\n");
printf("|                                  |\n");
printf("|                                  |\n");
printf("|                                  |\n");
printf("|                                  |\n");
printf("|                                  |\n");
printf("|                                  |\n");
printf("------------------------------------\n");
char i;
scanf("%c",&i);
return 0;
}


1 ncurses库程序的标准模式

#include <ncurses.h> //要包含头文件#include <curses.h>
int main()
{initscr();    //初始化 进入curses模式.................. endwin();  //退出curses模式return 0;
}

1.1 使用ncurses库 ,要包含头文件 #include <curses.h>;(ncurses名字中的n意味着new,即是new curses,假如使用的是curses库, 要加的头文件则是 #include <curses.h>)
1.2 编译时要加上-lncurses ,如 gcc a.c - lncurses,若想要生成自命名为abc的可执行文件,则编译时应为:gcc a.c - lncurses -o abc
1.3 initscr(); // 初始化,进入ncurses模式
1.4 endwin(); // 退出ncurses模式


2 ncurses库的常用函数

2.1 输入

getch(); // 输入一个字符
getstr(); // 输入一串字符串
scanw(“%s”,string); // 输入一串字符串

2.2 输出

addch(); // 显示一个字符
addstr(); // 显示一串字符串
printw(“%c”,变量);// 类似 printf 打印内容
refresh(); //刷新物理屏幕

在我们使用 printw 时,实际上这个数据被打印到一个叫作“stdscr”的虚拟窗口上,没有被直接输出到屏幕上。printw()函数的作用是不断将一些显示标记和相关的数据结构写在虚拟显示器上,并将这些数据写入 stdscr 的缓冲区内。所以,为了显示这些缓冲区中的数据我们必须使用 refresh() 函数告诉 ncurses 系统将缓冲区的内容输出到屏幕上。这种机制可以不断在虚拟屏幕上写入数据,而调用 refresh() 函数时让一切看起来似乎是一次完成的。因为 refresh() 函数只核查窗口和数据中变动的部分,这种富有弹性的设计提供了一个高效的反馈机制。所以说不断在虚拟屏幕上写入数据时,我们应该在 printw函数后加上refresh函数,这样才能实现不断实时显示,而一次的静态显示,可以只用printw。

2.3 keypad(win,bf)

呼叫 keypad 时须传入两个值:
win为 WINDOW 型态指标,通常传入标准输出入屏幕 stdscr,bf 为 TRUE 或 FALSE
当开启 keypad 后, 可以使用键盘上的一些特殊字元, 如上下左右等方向键
curses 会将这些特殊字元转换成 curses.h 内定义的一些特殊键,这些定义的特殊键通常以 KEY_ 开头

2.4 睡眠时间函数

sleep();//以秒为单位
unsigned int sleep(unsigned int seconds);
头文件
#include<unistd.h>
sleep()非系统调用,sleep()是在库函数中实现的,它是通过alarm()来设定报警时间,使用sigsuspend()将进程挂起在信号SIGALARM上。
sleep()只能精确到秒级上。sleep()会令目前的进程暂停,直到达到参数seconds 所指定的时间,或是被信号所中断。
return:若进程暂停到参数seconds 所指定的时间,成功则返回0,若有信号中断则返回剩余秒数。

usleep(); //以微秒为单位
unsigned int usleep(unsigned int useconds);
除了时间单位为微秒以外,在使用上与sleep()差不多。还有就是实现也是不同的,sleep因为是用alarm实现的,所以时间单位为s ,而usleep的时间单位为us(微妙) ,那肯定不是由alarm实现的,所以说它们的实现不同,但都是linux用的,而window下不能用,因为都是sleep和usleep都是在unistd.h下定义的。

特别提醒:退出ncurses程序运行的操作界面,按 Ctrl+c


3 基于Linux ncurses图形库的贪吃蛇小游戏的完整代码

#include <ncurses.h>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <time.h>
#include <unistd.h>//宏定义贪吃蛇上下左右移动的方向键
#define UP     1
#define DOWN  -1
#define LEFT   2
#define RIGHT -2struct Snack *head = NULL;      //贪吃蛇的头节点
struct Snack *tail = NULL;      //贪吃蛇的尾节点
int key;                //键值
int dir = 4;            //初始化蛇移动的方向
int score = 0;          //成绩/*游戏布局界面用结构体来初始化*/
struct Snack
{int hang;int lie;struct Snack *next;
};struct Snack food;      //定义结构体foodvoid initFood()
{int x = rand()%20;      //随机生成数取余,随机刷新食物的位置int y = rand()%20;if(x >= 1 && x < 20 && y >= 1 && y < 20){food.hang = x;food.lie = y;}
}
//初始化按键操作
void initNcurse(void)
{initscr();keypad(stdscr,1);noecho();
}
//判断随机生成食物的坐标与游戏框内的随机坐标
int hasSnackFood(int i,int j)
{if(food.hang == i && food.lie == j){return 1;       //相等返回1}return 0;
}//头节点head初始化函数
int hasSnackNode(int i,int j)
{struct Snack *p;p = head;while(p != NULL)                //判断头节点是否指向NULL{if(p->hang == i && p->lie == j)      //判断蛇的初始化坐标和hang,lie的坐标是否相等   {return 1;               //为1,打印蛇身节点}p = p->next;            //方便下一次循环判断是否为NULL}return 0;       //节点为NULL,返回0
}/*游戏界面设计用Ncurses图形库来做,定义gamePic函数初始化游戏界面*/
void gamePic(void)
{int hang;int lie;move(0,0);      //调用Ncurses图形库自带的move函数实现按键控制蛇的走位
/*实现游戏界面的上下左右边框*/for(hang=0;hang<20;hang++){if(hang==0)             //判断是否在第一行{for(lie=0;lie<20;lie++){printw("--");           //打印上边框}printw("\n");}if(hang>=0 && hang<=19){for(lie=0;lie<=20;lie++){if(lie == 0 || lie==20){printw("|");            //打印左右边框}else if(hasSnackNode(hang,lie)){               printw("[]");                   //打印蛇的身子}else if(hasSnackFood(hang,lie)){printw("##");                   //随机刷新食物}else{printw("  ");                   //打印空格}}printw("\n");}if(hang == 19){for(lie=0;lie<20;lie++){printw("--");           //打印下边框}printw("\n");printw("                   by MRDOCMAN,score = %d\n",score);}}
}void addNode()
{struct Snack *new;new = (struct Snack *)malloc(sizeof(struct Snack));new->next = NULL;//上下左右键控制蛇的走向switch(dir){case UP:new->hang = tail->hang-1;       //向上,头节点减一new->lie = tail->lie;break;case DOWN:new->hang = tail->hang+1;       //向下,头节点加一new->lie = tail->lie;break;case LEFT:new->hang = tail->hang;new->lie = tail->lie-1;         break;case RIGHT:new->hang = tail->hang;new->lie = tail->lie+1;break;}tail->next = new;tail = new;             //新加入的节点重新指向tail}void initSnack()
{/*使用链表的尾插法,移动时*/struct Snack *p;dir = RIGHT;while(head != NULL){p = head;head = head->next;free(p);}initFood();             //刷新食物head = (struct Snack *)malloc(sizeof(struct Snack));head->hang = 2;head->lie = 2;head->next = NULL;tail = head;addNode();addNode();}
//头节点删除,尾节点增加
void deleNode()
{struct Snack *p;p = head;head = head->next;free(p);
}int ifSnackDie()
{struct Snack *p;p = head;if(tail->hang<0 || tail->lie==0 || tail->hang==20 || tail->lie==20)     //判断蛇是否撞墙{return 1;}while(p->next != NULL){if(p->hang == tail->hang && p->lie == tail->lie){return 1;}p = p->next;}return 0;
}void moveSnack()
{addNode();if(hasSnackFood(tail->hang,tail->lie)){initFood();score+=1;               //食物重新刷新后,得分加一}else{deleNode();}if(ifSnackDie()){initSnack();score = 0;              //撞墙后得分清零}
}
//刷新游戏界面
void* refreshJieMian()
{while(1){moveSnack();gamePic();refresh();usleep(100000);}}void turn(int direc)
{if(abs(dir) != abs(direc)){dir = direc;}
}void* changeDir()
{while(1){key = getch();switch(key){case KEY_RIGHT:turn(RIGHT);break;case KEY_LEFT:turn(LEFT);break;case KEY_DOWN:turn(DOWN);break;case KEY_UP:turn(UP);break;}}}int main()
{pthread_t t1;pthread_t t2;initNcurse();initSnack();gamePic();pthread_create(&t1,NULL,refreshJieMian,NULL);pthread_create(&t2,NULL,changeDir,NULL);while(1);getch();endwin();return 0;
}


码字不易  求个三连

基于Linux ncurses图形库的贪吃蛇小游戏相关推荐

  1. 计算机毕业设计-基于Java的GUI实现贪吃蛇小游戏

    标题:基于Java多线程版本GUI贪吃蛇小游戏 1.项目技术点 1.多线程的运用. 2.JAVA的GUI的运用. 3.数据结构的灵活运用. 4.随机食物的生成. 5.关卡加速,随着蛇身增长,蛇的速度也 ...

  2. 基于A*算法的自动寻路贪吃蛇小游戏demo

    首先,先强调一下,因为只用了A*算法,所以不能吃满.其实就是自娱自乐的产物. 用QT写的. 网盘链接: https://pan.baidu.com/s/1tLwwTkk2Q5FQG5s4Y_Nv0w ...

  3. 基于C语言Ncurse库和链表的简单贪吃蛇小游戏

    参考:基于C语言Ncurse库和链表的简单贪吃蛇小游戏 作者:三速何时sub20 发布时间:2020-09-29 10:23:51 网址:https://blog.csdn.net/weixin_44 ...

  4. 基于STL实现自动贪心寻路算法的贪吃蛇小游戏

    基于STL实现自动贪心寻路算法的贪吃蛇小游戏 写贪吃蛇小游戏的想法来自CometOJ-Contest#13的B题,当时用STL双端队列维护蛇身的时候觉得非常方便,现在用EasyX图形库实现一下. 运行 ...

  5. 基于stm32、0.96寸OLED实现的贪吃蛇小游戏(详细源码注释)

    简介:本实验基于stm32最小系统.0.96寸OLED(68*128)和摇杆实现一个经典的贪吃蛇小游戏.项目源码地址:点击下载. 硬件设计: 普通摇杆,0.96寸OLED 单色屏幕(SPI协议通讯), ...

  6. 【精选】基于EasyX的贪吃蛇小游戏

    文章目录 前言 一.项目环境 1.Visual Studio 2019 2.EasyX 20200902 二.运行效果展示 0.加载游戏 1.主菜单 2.游戏设置 3.游戏说明 4.生存模式 5.无尽 ...

  7. 基于STM32的贪吃蛇小游戏

    基于STM32的贪吃蛇小游戏 初学32一个月,学的并不多,便想着做一个贪吃蛇小游戏,因为有51单片机做贪吃蛇的经验,所以实现出来并不困难. 作品简介 游戏面版将在4.3寸480*800)液晶上显示,初 ...

  8. 基于Stm32f407 的贪吃蛇小游戏【正点原子-探索者开发板】

    基于单片机stm32f407的单机小游戏----贪吃蛇小游戏 1.介绍 这是我花一个星期完成的一个简单地单机贪吃蛇小游戏项目,芯片是stm32f407,项目是基于正点原子-探索者开发板完成的,有需要的 ...

  9. 贪吃蛇小游戏 c++ easyx图形库实现

    贪吃蛇小游戏 c++ easyx图形库实现 实施思路 1.用上下左右键来控制方向 2.按enter键开始 暂停 3.通过随机函数来实现食物的随机出现 4.通过单链表来构造蛇 5.蛇撞墙    咬到自己 ...

最新文章

  1. java中getter_Java中的Getter和Setters解释了
  2. OKR的落实过程中如何判断设定的OKR是否是合格的OKR?
  3. 《精解Windows8》——2.6 Windows应用商店
  4. Create Maintenance Plans
  5. MPAndroidChart——饼图
  6. C# 模拟鼠标移动与点击
  7. postman模拟文件上传接口
  8. java改写weka中的算法_用Eclipse在Weka中嵌入新算法
  9. idea启动项目没错,可是debug却一直启动不起来
  10. Windows10-1909各个版本进行下载地址汇总
  11. Unity Android记录
  12. shell解析xml文件
  13. python学习笔记第六节(函数,装饰器)
  14. d3.js——饼状图
  15. html页面插歌,怎样在HTML播放器里插入歌曲
  16. 【文献心得】关于内核在不同芯片平台移植的相关整理
  17. 前端微信签名验证工具_微信网页开发如何完成签名校验
  18. 拼多多“出海”的三个考验?
  19. 如何开发微信小程序?(入门须知)
  20. angular时间格式化

热门文章

  1. D435i vins搜集资料
  2. 3.6 无限循环和循环嵌套
  3. 1 项目总结(编程项目+ 实验室项目)
  4. 【Coursera-Machine Learning】自用7
  5. Java数据结构之克里斯卡尔算法(Kruskal算法)
  6. 基于IDEA的SpringMVC+Spring+Mybatis的web项目环境搭建、目录解析、代码整合
  7. 【高级篇 / ZTNA】(7.0) ❀ 04. FortiClient 下载与安装 ❀ FortiGate 防火墙
  8. 《推动可持续社会价值创新》的意涵及对人才需求及个人陈述 (PS) 的启示
  9. python bgr转rgb_python-PIL旋转图像颜色(BGR- RGB)
  10. 从初级软件测试,到高级软件测试的必经之路