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

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/352770.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

高考复习技巧考研资料、美赛论文及代码,数据收集网站(初高中招生考试全科试卷等)

图&#xff0c;就要从“点、线、面的位置关系”这一内核开始发散&#xff0c;第一层级为彼此的位置关系&#xff0c;平行、相交、异面&#xff08;两直线间位置&#xff09;、垂直&#xff08;相交或异面中的特殊位置&#xff09;&#xff0c;多面体、旋转体等&#xff0c;然后…

【Java与网络6】实现一个自己的HTTP浏览器

前面我们讨论了HTTP协议的基本结构和Socket编程的基本原理&#xff0c;本文我们来整个大活&#xff1a;自己实现一个简单的浏览器。 目录 1.主线程循环体 2.readHostAndPort()方法的实现 3.readHttpRequest()方法的实现 4.sendHttpRequest()方法的实现 5.readHttpRespons…

由两个有限项的等差数列B, C, 求有多少个有限项的等差数列A,满足C是A, B的所有公共项,若有无穷个A满足条件,输出-1

题目 思路: #include <bits/stdc++.h> using namespace std; #define int long long #define pb push_back const int maxn = 1e6 + 5, inf = 1e9 + 5, maxm = 4e4 + 5, mod = 1e9 + 7, N = 1e6; // int a[maxn], b[maxn]; int n, m; string s;int qpow(int a, int b){…

Android P 屏保和休眠相关知识

Android P添加屏保功能&#xff0c;如果休眠时间设定大于屏保时间&#xff0c;则先进入屏保&#xff0c;达到休眠时间后再进入休眠 需求&#xff1a; 添加屏幕互保开关&#xff0c;默认关闭。只保留时钟&#xff0c;可设定指针和数字、夜间模式。启用时间改多长时间无操作进入…

Microsoft Visual Studio 2022的安装与使用

1 软件介绍 Microsoft Visual Studio 2022是Microsoft Visual Studio软件的一个高版本&#xff0c;能够编写和执行C/C代码&#xff0c;具有强大的功能&#xff0c;是开发C/C程序的主流软件。 Microsoft Visual Studio 2022有三个版本&#xff0c;分别是社区版&#xff08;Commu…

ACDSee 2024旗舰版 下载安装汉化教程,ACDSee 最新版,附安装包和工具,全网最简单,轻松搞的安装,无套路

前言 ACDSee是一款数字资产管理、图片管理编辑工具软件&#xff0c;提供良好的操作界面&#xff0c;简单人性化的操作方式&#xff0c;优质的快速图形解码方式&#xff0c;支持丰富的RAW格式&#xff0c;强大的图形文件管理功能等。 准备工作 1、提前准备好 ACDSee 2024 安装…

手把手教你优雅的安装虚拟机 Ubuntu —— 图文并茂

目录 Ubuntu 获取Vmware 安装新建虚拟机Ubuntu 安装虚拟机工具安装更多内容 本文教你如何优雅的在虚拟机中安装 Ubuntu&#xff0c;图文并茂、包教包会&#xff01; Ubuntu 获取 Ubuntu 官网镜像下载速度较慢&#xff0c;建议从国内镜像网站下载&#xff0c;如网易、中科大、…

针对于vue element-plus组件的el-date-picker日期区间组件的日期格式问题以及如何进行区间判断

<template><el-date-picker v-model"value1" type"daterange" range-separator"To" start-placeholder"开始日期" end-placeholder"结束日期" :size"size" change"sarend" /> </templat…

【网站项目】基于SSM的231论文投稿系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

《合成孔径雷达成像算法与实现》Figure5.19

clc clear close all距离向参数 R_eta_c 20e3; % 景中心斜距 Tr 25e-6; % 发射脉冲时宽 Kr 0.25e12; % 距离向调频率 Fr 7.5e6; % 距离向采样率 Nrg 256; % 距离线采样点数 Bw abs(Kr*Tr); …

【word visio绘图】关闭visio两线交叉的跳线(跨线)

【visio绘图】关闭visio两线交叉的跳线&#xff08;跨线&#xff09; 1 如何在Visio绘图中关闭visio两线交叉的跳线&#xff08;跨线&#xff09;第一步&#xff1a;打开Visio并创建您的图形第二步&#xff1a;绘制您的连接线第三步&#xff1a;关闭跳线第四步&#xff1a;手动…

XSS_Labs靶场通关笔记

每一关的方法不唯一&#xff1b;可以结合源码进行分析后构造payload&#xff1b; 通关技巧&#xff08;四步&#xff09;&#xff1a; 1.输入内容看源码变化&#xff1b; 2.找到内容插入点&#xff1b; 3.测试是否有过滤&#xff1b; 4.构造payload绕过 第一关 构造paylo…

软件设计师——计算机网络(四)

&#x1f4d1;前言 本文主要是【计算机网络】——软件设计师——计算机网络的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是听风与他&#x1f947; ☁️博客首页&#xff1a;CSDN主页听风与他 &#x1…

【心得】java JNDI配合RMI实现注入个人笔记

目录 JNDI RMI 基本概念 RMI 基本逻辑 恶意利用 JNDI注入RMI实现攻击 JNDI Java Naming and Directory Interface Java 命令和目录接口 让配置参数 和 代码 解耦的规范或者思想 低耦合 高内聚 Name 命名 java对象 通过 命名 绑定到 容器环境 java对象和一个特定的…

二分算法模版

二分算法模版 实数二分算法模版实数二分模版题 整数二分算法模版向上取整二分模版向下取整二分模版二分模版的注意点二分模版中check函数的实现能够使用二分的条件 二分主要分两类&#xff0c; 一类是对实数进行二分&#xff0c;一类是对整数进行二分 对整数二分又分成2种&…

分布式id-Leaf算法

一、介绍 由美团开发&#xff0c;开源项目链接&#xff1a;https://github.com/Meituan-Dianping/Leaf Leaf同时支持号段模式和snowflake算法模式&#xff0c;可以切换使用。ID号码是趋势递增的8byte的64位数字&#xff0c;满足上述数据库存储的主键要求。 Leaf的snowflake模…

谷歌vue插件安装包

链接&#xff1a;https://pan.baidu.com/s/1wTCqn7ttc-rF_wZScfEgPw?pwde7k6 提取码&#xff1a;e7k6 修改D:\谷歌浏览器插件安装包\devtools-main\packages\shell-chrome下manifest.json文件 将里面这四个文件地址改为src下面&#xff0c;因为地址在src下&#xff0c;直接…

Unity中URP下逐顶点光照

文章目录 前言一、之前额外灯逐像素光照的数据准备好后&#xff0c;还有最后的处理二、额外灯的逐顶点光照1、逐顶点额外灯的光照颜色2、inputData.vertexLighting3、surfaceData.albedo 前言 在上篇文章中&#xff0c;我们分析了Unity中URP下额外灯&#xff0c;逐像素光照中聚…

【RTP】webrtc 学习2: webrtc对h264的rtp打包

切片只是拷贝帧的split的各个部分到新的rtp 包的封装中。并没有在rtp包本身标记是否为关键帧FU-A 切片 输入的H.264 数据进行split :SplitNalu SplitNalu : 按照最大1200字节进行切分 切分后会返回一个数组 对于FU-A :split的数据总大小是 去掉一个字节的nalu header size …

高德地图实现-微信小程序地图导航

效果图&#xff1a; 一、准备阶段 1、在高德开放平台注册成为开发者2、申请开发者密钥&#xff08;key&#xff09;。3、下载并解压高德地图微信小程序SDK 高德开放平台&#xff1a; 注册账号(https://lbs.amap.com/)) 申请小程序应用的 key 应用管理(https://console.ama…