Flappy bird小游戏

一、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

相关推荐
Android系统攻城狮30 分钟前
Linux Gstreamer深度解析之gst_audio_ring_buffer_delay调用流程与实战(七十二)
linux·运维·服务器·gstreamer音视频·音视频进阶
快乐的韭菜根根1 小时前
ubuntu 安装slurm并配置
linux·运维·ubuntu
Tronlong创龙3 小时前
SBC‑TLT153 嵌入式 Linux 应用开发,交叉编译与 GDB 调试实践(上)
嵌入式硬件·嵌入式开发·硬件开发·工业控制·工业开发板
倒头就睡的小比特3 小时前
Linux基础指令3
linux·服务器
梦帮科技3 小时前
Kali Linux Scapy 畸形报文构造学——深度解剖非法 TCP Flags 与反常序列号
linux·爬虫·神经网络·算法·数学建模·系统架构·模拟退火算法
半杯咖啡半行码4 小时前
Linux 驱动开发入门:内核模块编程基础
linux·服务器·网络
别动我齐刘海5 小时前
Linux 系统调试学习2
linux·运维·c++·人工智能·学习·机器学习·机器人
龙虾电话5 小时前
语音机器人打断不进去:VAD 双阈值迟滞里一个共用的 bool,和它引发的连锁误判
linux
honsor5 小时前
机房IP化改造首选:以太网温湿度传感器,PoE供电+Modbus TCP一网搞定
linux·运维·服务器
默|笙6 小时前
【Linux网络】_udp_socket(认识)
linux·网络·udp