天天看點

C語言Flappy bird——Windows下基于EasyX且支援鍵盤操作

一、遊戲視窗

PS:此遊戲為c語言開發,因EasyX庫需要.cpp檔案才能編譯,是以工程檔案字尾為.cpp,并未使用cpp的文法。

VS2013工程百度雲連結:

連結:https://pan.baidu.com/s/16k2AvvEC_4NM_sFQHXgW1w

提取碼:2333

1.1遊戲界面

C語言Flappy bird——Windows下基于EasyX且支援鍵盤操作

1.2遊戲結束界面

C語言Flappy bird——Windows下基于EasyX且支援鍵盤操作

二、遊戲源碼

将flb.cpp、flb.h、main.cpp檔案添加到工程裡

2.1 flb.cpp

#include "flb.h"

#define Blank       0
#define Wall        1
#define Bird_Body   2

#define BIRD_HIGH   7
#define length      700
#define Door_WID    20

#define Wall_COLOR  YELLOW
#define KB_COLOR    CYAN

int WALL_DISTAN = 30;//牆壁間隔
IMAGE img;//存儲bird圖檔
IMAGE pWall_Img;//存儲Wall的圖檔
int Bird_MAP[100][100];//地圖
int Bird_pos[2] = { 9, 30 };//bird位置 Bird_pos[0]為橫坐标不變 Bird_pos[1]為縱坐标
int SUM_SCORE = -1;//總分數
int num_rand[20] = { 16, 45, 40, 10, 40, 55, 15, 0, 46, 15, 12, 60, 10, 45, 12, 50, 8, 35, 18, 47 };//牆的縫隙位置
int Door_pos = 0;//牆的縫隙位置數組下标
int t = 1;//下降時間
int t_count = 0;//下降時間計數

void OninitAll()
{
	for (int i = 0; i < 100; i++)
		for (int j = 0; j < 100; j++)
			Bird_MAP[i][j] = 0;//地圖清零
	//初始化bird的初始位置
	Bird_pos[0] = 9;
	Bird_pos[1] = 30;
	SUM_SCORE = -1;//分數清空
	Door_pos = 0;//門的位置num_rand數組下标清空
	WALL_DISTAN = 30;//重置牆的距離
	t = 1;//下降時間(距離)歸1
	t_count = 0;//下降時間計數清空
}
void Restart_Game()
{
	char str[50];//遊戲結束 彈出視窗顯示分數
	if (SUM_SCORE > 0)
		sprintf(str, "遊戲結束,得分:%d,是否重開?", SUM_SCORE);
	else
		sprintf(str, "遊戲結束,得分:%d,是否重開?", 0);
	int res = MessageBoxA(0, str, "Flappy bird", MB_YESNO | MB_SYSTEMMODAL);
	if (res == IDYES)//選擇是 則初始化參數再重開
	{
		OninitAll();
		Start_Game();
	}
	else//選擇否  關閉遊戲
	{
		closegraph();
		char str[30];
		sprintf(str, "taskkill /f /im \"%s\"", "Flappy bird.exe");
		system(str);
	}
}
void Create_WALL(int i, int Door_pos)
{
	int pos = 70;//門的上方位置為 pos - num_rand[Door_pos]
	for (int j = 0; j < 100; j++)
	{
		for (int k = 1; k <= 6; k++)		//牆壁寬6
			Bird_MAP[100 - k - WALL_DISTAN * i][j] = Wall;

		if (j == (pos - num_rand[Door_pos]))
		{
			j += Door_WID;//到達門的上方位置則j + Door_WID  即留出門的距離Door_WID
		}
	}
}
void judgegame()
{
	if (Bird_pos[1] > 100 || Bird_pos[1] < 0)//上或者下出地圖則遊戲結束
		Restart_Game();

	for (int i = 0; i <= 3; i++)//bird長寬為3倍BIRD_HIGH 此範圍下的數組是Wall則結束
		for (int j = 0; j <= 3; j++)
		if (Bird_MAP[Bird_pos[0] + i][Bird_pos[1] + j] == Wall)
		{
			Restart_Game();
		}
}
void Draw_Map()
{
	cleardevice();
	for (int i = 1; i < 100; i++)
	{
		for (int j = 9; j < 90; j++)
		{
			if (Bird_MAP[i][j] == Wall
				&&Bird_MAP[i - 1][j] != Wall
				&&Bird_MAP[i][j + 1] != Wall
				&&i - Bird_pos[0] >= -7)/*  Bird_pos[2]*/
			{   //牆 上半部分
				putimage(i * BIRD_HIGH - BIRD_HIGH / 2,
					0,
					40,
					j * BIRD_HIGH + BIRD_HIGH / 2,
					&pWall_Img, 0, 0);
				//牆 下半部分
				putimage(i * BIRD_HIGH - BIRD_HIGH / 2,
					(j + Door_WID) * BIRD_HIGH + BIRD_HIGH / 2,
					40,
					length,
					&pWall_Img, 0, 0);
			}
		}
	}
	putimage(Bird_pos[0] * BIRD_HIGH - BIRD_HIGH / 2, Bird_pos[1] * BIRD_HIGH - BIRD_HIGH / 2, &img);//輸出bird圖檔
	char str[10];//左上角顯示分數
	if (SUM_SCORE > 0)
		sprintf(str, "%d", SUM_SCORE);
	else
		sprintf(str, "%d", 0);
	outtextxy(10, 10, str);
	judgegame();//判斷遊戲是否結束
}
void MOVE_WALL()
{
	for (int i = 0; i < 100; i++)
	{
		for (int j = 0; j < 100; j++)
		{
			int wallnum = 0;
			if (Bird_MAP[i][j] == Wall)//此處為牆 則下一步讓左側為牆
			{
				Bird_MAP[i - 1][j] = Wall;
				wallnum++;
				Bird_MAP[i][j] = Blank;//前面的設為牆 此處設為牆
			}
			if (wallnum == 100)
			{
				i += 5;
			}
			if (i == 0)//到達最左側出地圖就清空牆壁
				Bird_MAP[i][j] = Blank;
		}
	}
}
void Change_Birdpos()
{
	t_count++;
	if (t_count % 4 == 0)//每下降四次 下降時間(距離)加1
	{
		if (t < 3) t++; //下降時間(距離)≤3
	}
	Bird_pos[1] += t;
}
void MOVE_BIRD()//移動鳥
{
	int key;
	if (_kbhit() != 0) //檢查目前是否有鍵盤輸入,若有則傳回一個非0值,否則傳回0  
	{
		while (_kbhit() != 0)  //可能存在多個按鍵,要全部取完,以最後一個為主  
			key = _getch(); //将按鍵從控制台中取出并儲存到key中
		if (GetAsyncKeyState(VK_SPACE) & 0x8000)
		{
			t = 1;//重新開始下降  是以下降時間(距離)設為最小
			Bird_pos[1] -= 10;
		}
	}
}
int Move_Speed()
{
	int res = 45 - SUM_SCORE / 10;//每過十道牆 Sleep等待的時間減1
	if (res >= 25)//最快不低于25
		return res;
	else return 25;
}
void change_wallpos(int num)
{
	for (int j = 0; j < num; j++)//随機打亂門的距離數組num_rand
	{
		int randnum = rand() % 10;
		int temp = num_rand[j];
		num_rand[j] = num_rand[j + randnum];
		num_rand[j + randnum] = temp;
	}
}
void Start_Game()
{
	initgraph(length, length);//初始化視窗 length預設為700
	HWND hwnd = GetHWnd();
	SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE));
	MoveWindow(hwnd, 0, 0, length, length, TRUE);//設定為左上角顯示
	setbkcolor(KB_COLOR);//設定背景色
	cleardevice();
	char s[10];
	sprintf(s, "1.png");
	loadimage(&img, s);//加載bird圖檔  名稱為1.png
	char wall_str[10] = "wall.bmp";
	loadimage(&pWall_Img, wall_str);
	change_wallpos(3);
	for (int i = 0; i < 2; i++)//先生成三道牆
		Create_WALL(i, i);

	for (int stepnum = 0;; stepnum++)
	{
		if (stepnum == WALL_DISTAN)//此時移動距離等于牆的距離WALL_DISTAN
		{
			change_wallpos(3);
			Create_WALL(0, Door_pos % 20);//地圖最右側産生一道牆			
			Door_pos++;//門的位置num_rand數組下标加一
			SUM_SCORE++;//分數加一
			stepnum = 0;//移動距離清零
			if ((Door_pos + 1) % 10 == 0) //每過十道牆 距離減2
			if (WALL_DISTAN > 20) //牆之間的距離不能小于20
				WALL_DISTAN -= 2;
		}
		Draw_Map();//顯示地圖
		Change_Birdpos();//監聽鍵盤輸入  控制bird向上移動
		MOVE_WALL();//移動牆壁
		MOVE_BIRD();//移動bird
		Sleep(Move_Speed());//等待
	}
}

           

2.1 flb.h

#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <conio.h>
#include <time.h>
#include <Windows.h>
#include <graphics.h>

void OninitAll();//初始化參數
void Restart_Game();//判斷重新開始遊戲
void Create_WALL(int i, int Door_pos);//生成牆壁
void judgegame();//判斷遊戲是否結束
void Draw_Map();//牆 bird
void MOVE_WALL();//地圖移動
void MOVE_BIRD(); //移動鳥
void Change_Birdpos(double t);//改變鳥的位置
int Move_Speed();//牆移動速度
void change_wallpos(int num);//改變牆的位置
void Start_Game();//開始遊戲

           

2.1 main.cpp

#include "flb.h"
#define Wall_COLOR  YELLOW
#define KB_COLOR    CYAN

int main()
{
	Start_Game();

	
	system("pause");
	return 0;
}

           

由 LiangJian 寫于 2019 年 10 月 15 日

繼續閱讀