C/C++实现字符版flappy bird

C版本

点子

用游戏函数框架和控制台,写一个flappy bird的程序,每次出现一个障碍物,玩家控制的小鸟(@)越过障碍物的缺口。

实现过程

1. 小鸟下落和操作上升

第一步实现一个简单下落的小鸟@,小鸟自己有重力,会下落,每次y坐标+1,按空格键上升。换句话说,这里只给小鸟一种操作,上升。

#include <cstdio>
#include <windows.h>
#include <conio.h>

HANDLE hout;                     //定义标准输出设备句柄
CONSOLE_SCREEN_BUFFER_INFO csbi; //定义窗口缓冲区信息结构体
CONSOLE_CURSOR_INFO curInfo;     //定义光标信息结构体
int bird_x, bird_y;
int width, height;
 
void gotoxy(int x, int y) { //移动光标
	COORD pos = {x, y};
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos); 
}
void hideCursor() {  //隐藏光标
	curInfo.bVisible = 0;
	curInfo.dwSize = 1;
	SetConsoleCursorInfo(hout, &curInfo);
} 
	
int initGame() {
	hout = GetStdHandle(STD_OUTPUT_HANDLE);          //获得标准输出设备句柄 
	GetConsoleScreenBufferInfo(hout, &csbi);   		 //获得窗口缓冲区信息
	GetConsoleCursorInfo(hout, &curInfo);            //获得控制台光标信息 
	
	width = 30, height = 20;
	bird_x = width / 10, bird_y = 5;
	
	hideCursor();  //隐藏光标 
}

void endGame() {
	CloseHandle(hout);  //关闭标准输出设备句柄
}

void updateWithInput() {
	char input;
	if (kbhit()) {
		input = getch();  
		if (input == ' ') bird_y -= 2;
	}
}

void updateWithoutInput() {	
	bird_y++;   //小鸟逐渐下落  
	Sleep(150); //减缓下落  
}

void show() {
	gotoxy(0, 0);
	for (int i = 0; i < height; ++i) {
		for (int j = 0; j < width; ++j) {
			if (i == bird_y && j == bird_x) printf("@"); //输出小鸟
			else printf(" ");
		}
		printf("\n");
	}
} 

int main() {
	initGame();
	while (1) {
		show();
		updateWithInput();
		updateWithoutInput();
	}
	endGame();
	return 0;
}

效果如下:

在这里插入图片描述

2. 输出障碍物并让其移动

同时显示小鸟和静止的障碍物,并让障碍物自己从右向左移动。障碍物是从上面向下一截,从下面向上一截,中间有一个空缺。用bar_yTop,bar_yDown,bar1_x来描述障碍物。修改如下:

...
int bar_yTop, bar_yDown, bar_x; //障碍物 

int initGame() {
	...
	bar_yTop = height / 4;
	bar_yDown = height / 2;
	bar_x = width - 5;
}


void updateWithoutInput() {	 
	...
	bar_x--;    //障碍物逐渐右移 
	Sleep(200); //减缓下落  
}

void show() {
	...
			else if ((i <= bar_yTop || i >= bar_yDown) && j == bar_x) printf("#");
	...
} 

...

在这里插入图片描述

3. 判断障碍物是否与小鸟相撞

看小鸟是否从障碍物的缝隙中通过,还是发生碰撞。碰撞后退出游戏循环。越过障碍显示得分。

#include <cstdio>
#include <windows.h>
#include <conio.h>
#include <time.h>

HANDLE hout;                     //定义标准输出设备句柄
CONSOLE_SCREEN_BUFFER_INFO csbi; //定义窗口缓冲区信息结构体
CONSOLE_CURSOR_INFO curInfo;     //定义光标信息结构体
int bird_x, bird_y;
int width, height;
int bar_yTop, bar_yDown, bar_x;  //障碍物  
int score;
int exitflag = 0;                //退出游戏循环标志 
 
void setSize(short len, short wid) { //设置窗口大小 
	COORD pos = {len, wid};
	SMALL_RECT rc = {0, 0, len - 1, wid - 1}; //坐标从0开始 
	// -- 设置窗口信息
	// @param	HANDLE	[in] 窗口句柄
	// @param	bool	[in] 意思不明,但在true时才起作用
	// @param	RECT *	[in] 分别指定窗口左上角坐标和右下角坐标
	// #return	bool		 成功返回非0值 
	SetConsoleWindowInfo(hout, true, &rc); 
	// -- 设置缓冲区大小
	// -- 长和宽不得小于控制台大小;不得小于系统最小限制。否则设置无效
	// @param	HANDLE	[in] 窗口句柄
	// @param	COORD	[in] 坐标结构,包含长和宽
	// #return	bool		 成功返回非0值
	SetConsoleScreenBufferSize(hout, pos); 
}
void gotoxy(int x, int y) { //移动光标
	COORD pos = {x, y};
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos); 
}
void hideCursor() {  //隐藏光标
	curInfo.bVisible = 0;
	curInfo.dwSize = 1;
	SetConsoleCursorInfo(hout, &curInfo);
} 
	
int initGame() {
	hout = GetStdHandle(STD_OUTPUT_HANDLE);          //获得标准输出设备句柄 
	GetConsoleScreenBufferInfo(hout, &csbi);   		 //获得窗口缓冲区信息
	GetConsoleCursorInfo(hout, &curInfo);            //获得控制台光标信息 
	hideCursor();  									 //隐藏光标
	
	setSize(width * 2, height * 2);                  //设置窗口大小 
	
	width = 30, height = 20;
	bird_x = width / 10, bird_y = 5; 
	
	bar_yTop = height / 4;
	bar_yDown = height / 2;
	bar_x = width - 5;
}

void endGame() {
	CloseHandle(hout); //关闭标准输出设备句柄
}

void updateWithInput() {
	char input;
	if (kbhit()) {
		input = getch();  
		if (input == ' ') bird_y -= 2;
	}
}

void updateWithoutInput() {	
	bird_y++;   //小鸟逐渐下落 
	bar_x--;    //障碍物逐渐右移 
	if (bar_x == bird_x) {
		if (bird_y > bar_yTop && bird_y < bar_yDown) score++;
		else {
			printf("游戏失败!");
			system("pause");
			exitflag = 1; 
		}
	}
	Sleep(200); //减缓下落  
}

void show() {
	gotoxy(0, 0);
	for (int i = 0; i < height; ++i) {
		for (int j = 0; j < width; ++j) {
			if (i == bird_y && j == bird_x) printf("@");
			else if ((i <= bar_yTop || i >= bar_yDown) && j == bar_x) printf("#");
			else printf(" ");
		}
		printf("\n");
	}
	printf("得分为:%d\n", score); 
} 

int main() {
	initGame();
	while (1) {
		show();
		updateWithInput();
		updateWithoutInput();
		if (exitflag) break;  //游戏失败, 满足退出条件 
	}
	endGame();
	return 0;
}

在这里插入图片描述

4. 障碍物循环出现

类似飞机游戏中敌机被击落或者超出屏幕范围后重新出现敌机,这里让障碍物在左边消失后在最右边循环出现。用rand()随机产生障碍物的缝隙的位置和大小,当然,要让小鸟通过。

void updateWithoutInput() {	
	bird_y++;   //小鸟逐渐下落 
	bar_x--;    //障碍物逐渐右移 
	if (bar_x < 0) {  //重新生成一个障碍物 
		bar_x = width;
		int temp = rand() % (int)(height * 0.8); 
		bar_yTop = temp - height / 10 - 1;  
		bar_yDown = temp + height / 10 + 1;
	}
	...
}

在这里插入图片描述
思考:

  • 如何同时显示多根柱子?提示:用x坐标数组合y坐标数组;或者用结构体。
  • 模拟重力效果,小鸟加速下落。
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在 Qt/C++ 中开发 Flappy Bird 游戏,实现小鸟按下空格键跳跃(向上移动)的功能可以通过以下步骤实现: 1. 首先,在你的游戏窗口中,确保你已经设置了键盘事件的接收: ```cpp setFocusPolicy(Qt::StrongFocus); ``` 2. 然后,在你的游戏窗口类中重写键盘事件函数 `keyPressEvent`: ```cpp void YourGameWindow::keyPressEvent(QKeyEvent *event) { if (event->key() == Qt::Key_Space) { // 在这里执行小鸟跳跃的操作 } } ``` 3. 在执行小鸟跳跃的操作之前,你需要设置一个速度变量,用来控制小鸟向上移动的距离。你可以使用一个 QTimer 来定时更新小鸟的位置。 4. 在你的游戏窗口类中定义一个 QTimer 对象和一个速度变量: ```cpp QTimer *timer; int birdSpeed; ``` 5. 在你的游戏窗口类的构造函数中初始化 QTimer 和速度变量,并连接 QTimer 的 timeout 信号到一个槽函数: ```cpp YourGameWindow::YourGameWindow(QWidget *parent) : QWidget(parent) { // 其他初始化代码... timer = new QTimer(this); birdSpeed = 5; // 调整速度大小 connect(timer, SIGNAL(timeout()), this, SLOT(updateBirdPosition())); timer->start(20); // 调整定时器的时间间隔 } ``` 6. 编写一个槽函数 `updateBirdPosition()`,在其中更新小鸟的位置,并在按下空格键时让小鸟向上移动: ```cpp void YourGameWindow::updateBirdPosition() { // 更新小鸟的垂直位置 birdY -= birdSpeed; // 其他代码... // 重绘游戏窗口 update(); } ``` 7. 最后,在 `keyPressEvent` 的条件判断中添加小鸟向上移动的代码: ```cpp void YourGameWindow::keyPressEvent(QKeyEvent *event) { if (event->key() == Qt::Key_Space) { // 小鸟向上移动的代码 birdY -= 30; // 调整向上移动的距离 } } ``` 这样,当用户按下空格键时,小鸟会向上移动一定距离。你可以根据需要自行调整速度、跳跃高度等参数。注意,以上代码只提供了实现的思路,具体的实现方式还需要根据你的游戏设计和代码结构进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

memcpy0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值