代码
#include <stdlib.h>
#include <signal.h>
#include <sys/time.h>
#include <curses.h>
#include <setjmp.h>
#define SCREEN_BOTTOM 23
#define SCREEN_WIDTH 79
#define SCREEN_MAN 18
#define CSPACE ' '
#define CWALL '*'
#define CMAN 'O'
#define CLINE_VER '|'
#define CLINE_HOR '_'
#define KEY_SPACE ' '
#define TICKER 150
typedef struct node {
int x, y;
int width, space;
struct node *next;
}Node;
int man_x = 0, man_y = SCREEN_MAN - 1;
int line_x;
int line_y;
int line_len = 0;
int flag = 0;
int run_out = 0;
int win_len = 0;
Node *head = NULL, *tail = NULL;
jmp_buf jmpBuf;
void init();
void init_head();
void init_wall();
void init_draw();
void line_ver_clear();
void line_ver();
void line_hor();
void key_ctl();
int set_ticker(int n_msec);
void sig_timer(int sig);
void man_run();
void modify_list();
Node *generate_node();
void reset();
void free_list();
int main()
{
_again:
if(setjmp(jmpBuf) != 0)
goto _again;
init();
while(1)
key_ctl();
return 0;
}
void key_ctl()
{
char ch = 0;
line_len = 0;
line_x = man_x + 1;
line_y = man_y;
run_out = 0;
win_len = 0;
do {
ch = getch();
} while(ch != KEY_SPACE);
flag = 1;
set_ticker(TICKER);
do {
ch = getch();
} while(ch != KEY_SPACE);
set_ticker(0);
line_ver_clear();
line_hor();
flag = 0;
line_y = man_y;
set_ticker(TICKER);
while(!run_out);
if(win_len < head->next->space ||
win_len > (head->next->space + head->next->next->width)) {
move(0, 0);
printw("try again? (y/n)");
refresh();
while(ch = getch()) {
if((ch == 'n') || (ch == 'N')) {
move(1, 0);
printw("you will quit the game in 2 seconds");
refresh();
sleep(2);
free_list();
endwin();
exit(0);
}
else if((ch == 'y') || (ch == 'Y')) {
longjmp(jmpBuf, 1);
}
else {
move(1, 0);
printw("please input y or n");
refresh();
}
}
}
else {
reset();
}
}
void reset()
{
modify_list();
clear();
init_draw();
}
void modify_list()
{
Node *p;
Node *tmp = head->next;
head->next = tmp->next;
for(p = head->next; p != NULL; p = p->next)
p->x -= (tmp->width + tmp->space);
free(tmp);
tmp = generate_node();
tail = tail->next = tmp;
man_x = head->next->x + head->next->width;
}
void sig_timer(int sig)
{
if(flag == 1) {
line_ver();
if(line_y < 0)
set_ticker(0);
}
else if(flag == 0) {
if(line_len <= 0) {
set_ticker(0);
run_out = 1;
}
man_run();
}
}
void line_ver_clear()
{
int i, j;
for(j = 1; j <= line_len; j++) {
move(line_y + j, line_x);
addch(CSPACE);
refresh();
}
}
void line_hor()
{
int i, j;
for(i = 1; i <= line_len; i++) {
move(man_y, man_x + i);
addch(CLINE_HOR);
refresh();
}
}
void line_ver()
{
move(line_y, line_x);
addch(CLINE_VER);
refresh();
line_y--;
line_len++;
win_len++;
}
void man_run()
{
static char ch = CSPACE;
move(man_y, ++man_x);
addch(CMAN);
refresh();
move(man_y, man_x - 1);
addch(ch);
refresh();
line_len--;
ch = '_';
}
void init()
{
initscr();
cbreak();
noecho();
curs_set(0);
srand(time(0));
clear();
init_wall();
init_draw();
signal(SIGALRM, sig_timer);
}
void init_head()
{
head = malloc(sizeof(Node));
head->next = NULL;
head->x = 0;
head->y = SCREEN_MAN;
head->width = 0;
head->space = 0;
tail = head;
}
Node *generate_node()
{
Node *tmp = malloc(sizeof(Node));
tmp->next = NULL;
do {
tmp->width = rand() % 10;
}while(tmp->width < 2);
do {
tmp->space = rand() % SCREEN_MAN - 1;
}while(tmp->space < 2);
tmp->x = tail->x + tail->width + tail->space;
tmp->y = tail->y;
return tmp;
}
void free_list()
{
Node *p;
if(head != NULL && head->next != NULL) {
for(p = head->next; p != NULL; p = p->next) {
free(p);
}
}
}
void init_wall()
{
int len = 0;
Node *tmp;
free_list();
init_head();
while(len < SCREEN_WIDTH) {
tmp = generate_node();
tail = tail->next = tmp;
len += (tail->width + tail->space);
}
man_x = head->next->x + head->next->width;
}
void init_draw()
{
Node *p;
int i, j;
for(p = head->next; p != NULL; p = p->next) {
for(i = p->x; i <= (p->x + p->width); i++) {
for(j = p->y; j <= SCREEN_BOTTOM; j++) {
move(j, i);
addch(CWALL);
refresh();
}
}
}
move(man_y, man_x);
addch(CMAN);
refresh();
}
int set_ticker(int n_msec)
{
struct itimerval timeset;
long n_sec, n_usec;
n_sec = n_msec / 1000;
n_usec = (n_msec % 1000) * 1000L;
timeset.it_interval.tv_sec = n_sec;
timeset.it_interval.tv_usec = n_usec;
timeset.it_value.tv_sec = n_sec;
timeset.it_value.tv_usec = n_usec;
return setitimer(ITIMER_REAL, ×et, NULL);
}
结果
视频
c语言小游戏