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座標數組;或者用結構體。
  • 模擬重力效果,小鳥加速下落。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章