目录
项目安排:
阶段1:初始化工作,小鸟功能实现
阶段2:管道功能实现
阶段3:完善代码,进行项目总结
1 阶段
1.1 初始化Ncurses库
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <curses.h>
#include <stdlib.h>
void init_curses()
{
initscr();
curs_set(0); //禁止光标显示
noecho(); //禁止输入字符显示
keypad(stdscr, 1); //启动功能按键
start_color();
init_pair(1,COLOR_WHITE, COLOR_RED);//小鸟颜色设置
init_pair(2,COLOR_WHITE, COLOR_GREEN);//管道颜色设置
}
1.2 设置定时时间
int set_timer(int ms_t)//设置定时器--ms
{
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;
}
1.3 实现小鸟功能(显示小鸟、清除小鸟、移动小鸟)
#define BIRD '@'
#define BLANK ' '
#define PIPE '+'
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(1);
}
}
}
}
2 阶段
2.1 创建链表
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 < 5; i++)
{
new = (Pipe_list)malloc(sizeof(Pipe_node));
new->x = (i + 1) * 20;
new->y = + 5; // (5-15行)
new->next = NULL;
p->next = new;
p = new;
}
tail = p;
}
2.2 显示管道
/*定义关于管道的结构体*/
typedef struct Pipe{
int x;//列坐标
int y;//横坐标
struct Pipe *next;
}Pipe_node, *Pipe_list;
Pipe_list head, tail;
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));
}
2.3 清除管道
即把显示管道的字符改为空格
void clear_pipe()
{
Pipe_list p;
int i,j;
p = head->next;
while(p != NULL)
{
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;
}
}
2.4 移动管道
void move_pipe()
{
Pipe_list p;
p = head->next;
while(p)
{
p->x--;
p = p->next;
}
}
3 阶段
3.1 判断游戏结束:小鸟与管道碰到
void handle(int sig)
{
Pipe_list p, new;
int i,j;
//小鸟自动下落
clear_bird();
g_bird_y++;
show_bird();
//判断游戏是否结束
if((char)inch() == PIPE)
{
set_timer(0);
endwin();
exit(1);
}
//管道自动左移
p = head->next;
if(p->x == 0)
{
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;
}
clear_pipe();
move_pipe();
show_pipe();
}
3.2 循环创建管道
同上
3.3 为管道和小鸟添加色彩
同上
4 完整代码:
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <curses.h>
#include <stdlib.h>
#define BIRD '@'
#define BLANK ' '
#define PIPE '+'
typedef struct _Pipe_node
{
int x;
int y;
struct _Pipe_node * next;
}Pipe_node, *Pipe_list;
int g_bird_y,g_bird_x;
Pipe_list head,tail;
void init_curses();
int set_timer(int ms);
void handle(int sig); //闹钟信号回调处理
void show_bird();
void clear_bird();
void move_bird();
void creat_list();
void show_pipe();
void clear_pipe();
void move_pipe();
int main(int argc,char *argv[])
{
g_bird_y = 15;
g_bird_x = 20;
init_curses();
signal(SIGALRM, handle);
set_timer(300);
srand(time(0)); //随机种子,不然每次开机都是一样的路线
creat_list();
show_bird();
move_bird();
while(1)
{
}
return 0;
}
void init_curses()
{
initscr();
curs_set(0); //禁止光标显示
noecho(); //禁止输入字符显示
keypad(stdscr, 1); //启动功能按键
start_color();
init_pair(1,COLOR_WHITE, COLOR_RED);//小鸟颜色设置
init_pair(2,COLOR_WHITE, COLOR_GREEN);//管道颜色设置
}
int set_timer(int ms)
{
struct itimerval timer;
long t_sec,t_usec;
int ret;
t_sec = ms / 1000; //s
t_usec = (ms % 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(g_bird_y,g_bird_x);
addch(BIRD);
refresh();
attroff(COLOR_PAIR(1));
}
void clear_bird()
{
move(g_bird_y,g_bird_x);
addch(BLANK);
refresh();
}
void move_bird()
{
char ch;
while(1)
{
ch = getch();
if(ch == BLANK)
{
clear_bird();
g_bird_y--;
show_bird();
}
}
}
void creat_list()
{
Pipe_list p, new;
int i;
head = (Pipe_list)malloc(sizeof(Pipe_node));
head->next = NULL;
p = head;
for(i = 0; i < 5; i++)
{
new = (Pipe_list)malloc(sizeof(Pipe_node));
new->x = (i + 2) * 20; //20 40 60 80 100
new->y = rand() % 11 + 5; // (0 + 5) <= y < (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 != NULL)
{
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 != NULL)
{
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;
}
}
void handle(int sig)
{
Pipe_list p, new;
int i,j;
//小鸟自动下落
clear_bird();
g_bird_y++;
show_bird();
//判断游戏是否结束
if((char)inch() == PIPE)
{
set_timer(0);
endwin();
exit(1);
}
//管道自动左移
p = head->next;
if(p->x == 0)
{
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;
}
clear_pipe();
move_pipe();
show_pipe();
}