一、Ncurses库
(1):Ncurses向用户提供了一个灵活高效的应用程序接口(API),它提供了创建窗口界面,移动光标,产生颜色以及处理键盘按键等功能。通俗点来说,它就是一个管理应用程序在字符终端显示的函数库。
(2):安装Ncurses库的命令--> sudo apt-get install libncurses5-dev
(3):在本项目中使用到的函数
initscr(void);
是curses模式的入口。将终端屏幕初始化为curses模式,为当前屏幕和相关的数据结构分配内存。
int endwin(void);
是curses模式的出口,退出curses模式,释放curses子系统和相关数据结构占用的内存。
int curs_set(int visibility); 设置光标是否可见,visibility:0(不可见),1(可见)
int move(int new_y, int new_x); 将光标移动到new_y所指定的行和new_x所指定的列
int addch(const chtype char); 在当前光标位置添加字符
int refresh(void); 刷新物理屏幕。将获取的内容显示到显示器上。
int keypad(WINDOW *window_ptr, bool key_on);
允许使用功能键。exp:keypad(stdscr,1);//允许使用功能按键
int getch(void); 读取键盘输入的一个字符
chtype inch(void); 获取当前光标位置的字符。
注:curses有自己的字符类型chtype,使用时强制类型转换为char
int start_color(void); 启动color机制,初始化当前终端支持的所有颜色
int init_pair(short pair_number, short foreground, short background); 配置颜色对
COLOR_BLACK 黑色 COLOR_MAGENTA 品红色
COLOR_RED 红色 COLOR_CYAN 青色
COLOR_GREEN 绿色 COLOR_WHITE 白色
COLOR_YELLOW 黄色 COLOR_BLUE 蓝色
int COLOR_PAIR(int pair_number);
设置颜色属性,设置完颜色对,可以通过COLOR_PAIR实现
int attron(chtype attribute); 启用属性设置
int attroff(chtype attribute); 关闭属性设置
二、运行代码
#include <stdio.h>
#include <stdlib.h>
#include <curses.h>
#include <signal.h>
#include <sys/time.h>
#define BIRD '@' //@表示小鸟#define BLANK ' ' //空格表示空格
#define PIPE '+' //+表示管道
int bird_y,bird_x; //小鸟坐标
/*定义关于管道的结构体*/
typedef struct Pipe{
int x; //列坐标
int y; //横坐标
struct Pipe *next;
}Pipe_node,*Pipe_list;
Pipe_list head,tail; //头尾结点
/*创建链表*/
void creat_list(){
int i;
Pipe_list p,new;
head = (Pipe_list)malloc(sizeof(Pipe_node));
head->next = NULL;
p = head;
for(i=0;i<6;i++){
new = (Pipe_list)malloc(sizeof(Pipe_node));
new->x = (i+1)*20;
new->y = rand()%11+5; //管道5-15行
new->next = NULL;
p->next = new;
p = new;
}
tail = p;
}
/*显示管道*/
void show_pipe(){
Pipe_list p;
int i,j;
p = head->next;
attron(COLOR_PAIR(2));
while(p){
for(i=p->x;i<p->x+10;i++){
/*创建上半部分管道*/
for(j=0;j<p->y;j++){
move(j,i);
addch(PIPE);
}
/*创建下半部分管道*/
for(j=p->y+5;j<25;j++){
move(j,i);
addch(PIPE);
}
}
refresh();
p = p->next;
}
attroff(COLOR_PAIR(2));
}
/*清除管道*/
void clear_pipe(){
Pipe_list p;
int i,j;
p = head->next;
while(p){
for(i=p->x;i<p->x+10;i++){
/*清除上半部分管道*/
for(j=0;j<p->y;j++){
move(j,i);
addch(BLANK);
}
/*清除下半部分管道*/
for(j=p->y+5;j<25;j++){
move(j,i);
addch(BLANK);
}
}
refresh();
p = p->next;
}
}
/*移动管道*/
void move_pipe(){
Pipe_list p;
p = head->next;
while(p){
p->x--;
p = p->next;
}
}
/*初始化Ncurses库*/
void init_curses(){
initscr(); //进入curses模式
curs_set(0); //禁止光标显示
noecho(); //禁止输入字符显示
keypad(stdscr,1); //允许功能键在当前窗口使用
start_color(); //启动颜色机制
init_pair(1,COLOR_WHITE,COLOR_RED); //设置小鸟颜色,字体白色,背景红色
init_pair(2,COLOR_WHITE,COLOR_GREEN); //设置管道颜色
}
/*设置定时器,参数为毫秒(ms)*/
int set_timer(int ms_t){
struct itimerval timer;
long t_sec,t_usec;
int ret;
t_sec = ms_t / 1000; //s
t_usec = (ms_t % 1000) * 1000; //us
timer.it_value.tv_sec = t_sec;
timer.it_value.tv_usec = t_usec; //首次启动定时值
timer.it_interval.tv_sec = t_sec;
timer.it_interval.tv_usec = t_usec; //之后每次启动的定时值
ret = setitimer(ITIMER_REAL,&timer,NULL); //启动定时器
return ret;
}
/*显示小鸟*/
void show_bird(){
attron(COLOR_PAIR(1));
move(bird_y,bird_x);
addch(BIRD);
refresh();
attroff(COLOR_PAIR(1));
}
/*清除小鸟*/
void clear_bird(){
move(bird_y,bird_x);
addch(BLANK);
refresh();
}
/*移动小鸟*/
void move_bird(){
char key;
while(1){
key = getch();
if(key==' '){
clear_bird();
bird_y--;
show_bird();
/*游戏结束判断*/
if((char)inch()==PIPE){
set_timer(0); //停止定时
endwin(); //退出模式
exit(0); //结束程序
}
}
}
}
void handler(int sig){
Pipe_list p,new;
//小鸟下落
clear_bird();
bird_y++;
show_bird();
//管道的循环创建
p = head->next;
if(p->x==0){
int i,j;
head->next = p->next;
for(i=p->x;i<p->x+10;i++){
/*清除上半部分管道*/
for(j=0;j<p->y;j++){
move(j,i);
addch(BLANK);
}
/*清除下半部分管道*/
for(j=p->y+5;j<25;j++){
move(j,i);
addch(BLANK);
}
refresh();
}
free(p);
new = (Pipe_list)malloc(sizeof(Pipe_node));
new->x = tail->x+20;
new->y = rand()%11+5;
new->next = NULL;
tail->next = new;
tail = new;
}
/*游戏结束判断*/
if((char)inch()==PIPE){
set_timer(0); //停止定时
endwin(); //退出模式
exit(0); //结束程序
}
//管道左移
clear_pipe();
move_pipe();
show_pipe();
}
/*主函数*/int main(int argc,const char *argv[]){
bird_y = 15; //行
bird_x = 15; //列
init_curses();
signal(SIGALRM,handler);
set_timer(500); //定时时间为500毫秒
srand(time(0)); //随机种子:每次启动的管道长度不一样
creat_list();
show_pipe();
show_bird();
move_bird();
return 0;
}
编译程序时要链接到Ncurses库即添加参数 -lncurses