基于ncurse的floppy_bird小游戏

1. 需求分析

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

2. 概要设计

2.1 鸟运动部分

在这里插入图片描述

2.2 杆的运动

在这里插入图片描述

3. 代码实现

#include <stdio.h>
#include <ncurses.h>

#include <stdlib.h>
#include <time.h>



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. 效果图

在这里插入图片描述

相关推荐

  1. 基于STM32嵌入式拼图游戏设计

    2024-01-28 21:46:03       36 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-01-28 21:46:03       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-28 21:46:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-28 21:46:03       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-28 21:46:03       20 阅读

热门阅读

  1. 力扣365-水壶问题

    2024-01-28 21:46:03       31 阅读
  2. Mybatis的XML配置

    2024-01-28 21:46:03       38 阅读
  3. MyBatis --- 常用注解

    2024-01-28 21:46:03       31 阅读
  4. 前端-打卡每日面试题-数据类型(2024.1.26)

    2024-01-28 21:46:03       35 阅读
  5. 分巧克力(二分实现C++)

    2024-01-28 21:46:03       31 阅读