棍子英雄

代码

/*
 * play : press space to start and again to stop
 * note : please play it in full screen
 */

#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, &timeset, NULL);
}

结果

这里写图片描述

视频

c语言小游戏

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值