基于ncurse的floppy_bird小游戏

1. 需求分析

将运动分解为鸟的垂直运动和杆的左右运动。

2. 概要设计

2.1 鸟运动部分

基于ncurse的floppy_bird小游戏_第1张图片

2.2 杆的运动

基于ncurse的floppy_bird小游戏_第2张图片

3. 代码实现

#include 
#include 

#include 
#include 



int vx = 0;
int vy = 1;

int bird_r;
int bird_c;

int rows;
int cols;

int bird_init_x = 5;
int bird_init_pole_gap = 6;


int last_fly_time = 1;
int up_time = 3;


int pole_width = 3;
int pole_bt_gap = 6;
int pole_in_gap = 6;



int pass_pole_nums = 0;
int pole_nums;


struct _pole_node {
    int pole_lb_x;
    int pole_gap_y;
};

typedef struct _pole_node pole_node;

pole_node pn[100];
int pole_nxt;




enum HIT_STATUS {
    HIT_NORMAL,
    HIT_GROUND,
    HIT_POLE,
};

enum GAME_STATUS {
    GAME_NORMAL,
    GAME_QUIT,
};


void reset_vy()
{
    vy = 1;
}

void set_pole_nums( )
{
   int tot = cols - bird_init_x - 2;

   tot -= bird_init_pole_gap;
   
   pole_nums = tot /( pole_width + pole_bt_gap );


}
void gen_next_pole(pole_node *prev, pole_node *cur )
{
    if ( !prev || !cur )
	    return;
    cur->pole_lb_x = prev->pole_lb_x + pole_bt_gap + pole_width;


    int prev_y = prev->pole_gap_y;

       int ub = prev_y - pole_bt_gap - pole_in_gap + 1;
       ub = ub < pole_width + 1 ? pole_width + 1: ub;

       int lb = prev_y + pole_bt_gap + pole_in_gap - 1;
       lb = lb > rows - 1 - pole_width  - pole_in_gap ? rows - 1 - pole_in_gap - pole_width : lb;

       cur->pole_gap_y = ub + rand() % (lb - ub + 1);           
    


}

void init_pole_bound()
{
   
    // pole_fp = 0;
//    pole_bp = pole_nums - 1;
    pn[0].pole_lb_x = bird_init_x + bird_init_pole_gap + 1;
    pn[0].pole_gap_y = ( bird_r - bird_init_pole_gap) + (rand()%(2 * bird_init_pole_gap)); 


    int prev_y;
    for ( int i = 1; i < pole_nums; ++i) {

       gen_next_pole( pn + i - 1, pn + i );
	    /*
       pn[i].pole_lb_x = pn[ i - 1].pole_lb_x  + pole_bt_gap + pole_width;
       prev_y = pn[ i - 1 ].pole_gap_y;
     

       int ub = prev_y - pole_bt_gap - pole_in_gap + 1;

       ub = ub < pole_width + 1 ? pole_width + 1: ub;

       int lb = prev_y + pole_bt_gap + pole_in_gap - 1;

       lb = lb > rows - 1 - pole_width  - pole_in_gap ? rows - 1 - pole_in_gap - pole_width : lb;

       pn[i].pole_gap_y = ub + rand() % (lb - ub + 1);           
     */ 
    }
}


void bird_fly( )
{
    vy = -1;
    up_time = last_fly_time;
}


int check_hit( )
{
    if ( bird_r - 1 == rows )
	    return HIT_GROUND;
   
    int nx = pn[pole_nxt].pole_lb_x;
    int ny = pn[pole_nxt].pole_gap_y;

    if ( bird_c >= nx && bird_c < nx + pole_width) {
        if ( bird_r < ny || bird_r >= ny + pole_in_gap )
		return HIT_POLE;
    }

    return HIT_NORMAL;
}

void pole_move( )
{
   for ( int i = 0; i < pole_nums; ++i) {
   
       pn[i].pole_lb_x--;
       int pole_rb = pn[i].pole_lb_x + pole_width - 1;
       if ( pole_rb < 1) {
           int idx = ( i - 1 + pole_nums ) % pole_nums;
           gen_next_pole( pn + idx, pn + i);
       }


   }

   if ( pn[pole_nxt].pole_lb_x + pole_width == bird_c ) {
	  pole_nxt = ( pole_nxt + 1 ) % pole_nums;
          pass_pole_nums++;
   }

}
void bird_move( )
{
    bird_r += vy;
    bird_c += vx; 
    
    if ( up_time) {
        up_time--;

	if ( !up_time ) {
            vy = 1;
	}
    }

    if ( bird_r < 1)
	    bird_r = 1;
}


void draw_wall(  )
{
    box(stdscr, '#', '#');

}
void draw_pole() 
{
   for ( int j = 0; j < pole_nums; ++j ) {
       for ( int i = 1; i < rows - 1; ++i) {
   
           if ( i >= pn[j].pole_gap_y && i < pn[j].pole_gap_y + pole_in_gap)
	       continue;
           for ( int k = 0; k < pole_width; ++k) {
	           int curx = pn[j].pole_lb_x + k;
		   int cury = i;

		   if ( curx > 0 && curx < cols - 1 && cury > 0 && cury < rows - 1)
		       mvaddch(cury, curx, '*');
	   }
       }	   
   }

}


void draw_bird( )
{
    mvaddch( bird_r, bird_c, '@');
}
void draw_tips( )
{
   int mid_r = LINES / 2;
   int bg_c = COLS - 20;

   mvprintw(mid_r, bg_c,"scores: %d", pass_pole_nums );
   mvprintw(mid_r + 1, bg_c, "Q: quit");
 

}
void draw_frame( )
{
    clear();
    draw_wall();
    draw_bird();
    draw_pole();
    draw_tips();
    refresh();
}





void get_rows_cols(int *prows, int *pcols)
{
    if ( !prows || !pcols)
	    return;

    *prows = LINES; 
    *pcols = COLS - 20;

}

void init_ncurse_settings( )
{
    initscr();
    noecho(  );
    timeout( 0 );

    curs_set( 0 );
}






int process_input( int ch )
{

    switch ( ch )
    {
        case 'Q':
        case 'q':
		    return GAME_QUIT;
	    case 'j':
	    case 'J':
	        bird_fly();
                break;		

    }
    
    return GAME_NORMAL;
}

int main( int argc, char *argv[])
{

    srand( (unsigned)time(NULL));
   init_ncurse_settings();


    get_rows_cols( &rows, &cols );

    set_pole_nums();
 


    bird_r = ( rows - 2) / 2;
    bird_c = bird_init_x;

    int ch;
   init_pole_bound();
   

    while ( 1 ) {
        usleep( 300000 );
        if ( check_hit() )
		break;
	ch = getch();
        int ret = process_input( ch );
            
        
	if ( ret == GAME_QUIT )
		break;

	    bird_move();
        pole_move();
	    draw_frame();
    }

   
   endwin();
    return 0;
}

4. 效果图

基于ncurse的floppy_bird小游戏_第3张图片

你可能感兴趣的:(ncurse,c语言)