Flappy_Bird1(C语言版)

多文件编程

这个小游戏Flappy_Bird1(C语言版)代码,采用了多文件编程。
那么多文件编程有什么好处呢?

1.便于复用代码。通用性强的重复的功能只要写一遍就可以了,下次要用在其它程序上时只要更改很小的部分或者可以不用更改。
2.便于多人协作。在设计软件之初就可以很清楚地分配各个开发部门的任务。模块的编写者本身只要关注他所写的东西,清楚这一部分的功能,留出接口就可以了。另外,对于整个工程的负责人而言,这样会方便浏览全局的工作进度,统筹人员安排。
3.便于修改和维护。如果能确定只是某个模块有问题,在模块内解决即可,不需要牵一发而动全身。要升级某一部分的功能,可以只针对具体的模块重新开发,节约成本。

关于多文件编程中涉及的知识参考《C Primer Plus》 第12章

代码讲解

一.打开编译器(我使用的是VS2019)新建一个工程文件夹,命名为Flappy_Bird1
二.Ctrl+shift+A新建一个.h文件,命名为Header.h.

注意我们将工程中用到的头文件全部存放到这里,这里文件的名称用于后面的引用。
现在我们先不在这个文件中写代码,等后面用到头文件时在往里面添加。

三.新建一个.cpp文件这里将其命名为:界面模块.cpp

在这个文件中我们来打印出游戏的界面

首先我们介绍两个辅助函数

1.gotoxy(),其作用为光标移动到(x,y)位置,在游戏中打印一张画面后将光标拉到(x,y)处进行打印。

void gotoxy(int x, int y) //光标移动到(x,y)位置,在游戏中打印一张画面后将光标拉到(x,y)处进行打印。
{
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	COORD pos;
	pos.X = x;
	pos.Y = y;
	SetConsoleCursorPosition(handle, pos);
}

2.HideCursor(),其作用为隐藏光标

void HideCursor()	  //隐藏光标
{
	CONSOLE_CURSOR_INFO cursor_info = { 1, 0 };
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}

我们只需知道这两个函数的作用即可.

打印游戏界面时,我们需要用到printf(),故需要向Header.h中添加标准输入输出的头文件stdio.h
Flappy_Bird1(C语言版)_第1张图片
通过图片来获取我们需要的参数。
界面尺寸high,width,小鸟坐标 bird_x,bird_y 障碍物的位置与形状确定需要的参数:bar_x,bar_y_up,bar_down_up。这里注意bar_y_up 初始化:

void startup(void)   //初始化参数设置
{
	high = 20;
	width = 20;
	bird_x = width / 3;
	bird_y = high / 2;
	bar_x = width / 3;
	bar_y_up = high / 4;
	bar_y_down = high / 2;
	score = 0;
}

接下来我们来打印界面 ,我们很容易想到(如果这个词伤害到了你,我表示深深的歉意)用for循环嵌套将界面绘制出来
奉上代码:

void game_bg(void)//绘制游戏背景
{
    gotoxy(0, 0);//将光标拉到左上角,然后进行下一轮的打印。
	HideCursor();//隐藏光标
	int i, j;
	for (i = 1; i <= high; i++)
	{
		for (j = 1; j <= width; j++)
		{
			if (i == bird_y && j == bird_x)
				printf("□");
			else if (i == 1 || i == high || j == 1 || j == width)
				printf("■");
			else if (j == bar_x && (i <= bar_y_up || i >= bar_y_down))
				printf("■");
			else
				printf("  ");//注意这里空格的长度应和■,□的长度一致,否则会出现错位的现象.
		}
		printf("\n");
	}
	printf("得分:%d\n", score);
}

我们可以在后续运行时将辅助函数注释掉看看会发生什么情况

到这里游戏界面搭建完成

四.新建:音乐模块.cpp

这里我们在项目文件夹Flappy_Bird1中新建一个文件夹命名music,将用到的音乐资源存放到这里
Flappy_Bird1(C语言版)_第2张图片
Flappy_Bird1(C语言版)_第3张图片

这里我们用到mciSendString函数来实现对音乐的播放,需要windows.h,以及宏定义#pragma comment(lib,“winmm.lib”),添加到Header.h中

#include"Header.h"
void background_music(void)//背景音乐
{
	mciSendString(TEXT("open  music\\backgroundmusic.mp3 alias background_music"), NULL, 0, NULL);
	mciSendString(TEXT("play background_music"), NULL, 0, NULL);
	mciSendString(TEXT("close  music\\backgroundmusic.mp3"), NULL, 0, NULL);
}
void fly_music(void)//飞行音乐
{
	mciSendString("play fly_music", NULL, 0, NULL);
	mciSendString("open  music\\fly.mp3 alias fly_music", NULL, 0, NULL);
	mciSendString("close fly_music", NULL, 0, NULL);
}
void score_music(void)//得分声音
{
	mciSendString("play score_music", NULL, 0, NULL);
	mciSendString("open  music\\scoremusic.mp3 alias score_music", NULL, 0, NULL);
}
void dash_music(void)//撞击声
{
	mciSendString("close background_music", NULL, 0, NULL);
	mciSendString("close fly_music", NULL, 0, NULL);
	mciSendString("open  music\\dashmusic.mp3 alias dash_music", NULL, 0, NULL);
	mciSendString("play dash_music", NULL, 0, NULL);

}
void gameover_music(void)//游戏结束声
{
	mciSendString("open  music\\gameovermusic.mp3 alias gameover_music", NULL, 0, NULL);
	mciSendString("play gameover_music", NULL, 0, NULL);
}

五.新建.cpp文件命名为:游戏模块.cpp

这个文件中用到了界面模块.cpp中定义的变量,利用其外部链接及文件作用域,在这里我们要做一下引用试声明。同理对音乐函数也进行引用。

引用:
Flappy_Bird1(C语言版)_第4张图片

void UpdateWithoutInput(void)//无输入时,界面的更新
{
	srand(time(0));
	background_music();
	bird_y++;
	bar_x--;
	if (bird_x == bar_x)
	{
		if (bird_y > bar_y_up && bird_y < bar_y_down)
		{
			score_music();
			score++;
		}
		else
		{
			dash_music();
			gameover_music();
			system("CLS");//清屏,把打印的游戏界面清除。
			printf("Game Over!\n");
			printf("得分:%d\n", score);
			system("pause");
			exit(0);
		}
	}
	if (bar_x < 0)
	{
		bar_x = width;
		int temp = rand() % (int)(high * 0.8);
		bar_y_down = temp + high / 5;
		bar_y_up = temp - high / 5;
	}
	if ((bird_y >= high) || (bird_y <= 1))
	{
		dash_music();
		gameover_music();
		system("CLS");//清屏,把打印的游戏界面清除。
		printf("Game Over!\n");
		printf("得分:%d\n", score);
		system("pause");
		exit(0);
	}
	Sleep(100);
}
void UpdateWithInput(void)//按键操作后对界面的更新
{
	if (_kbhit())
		if (_getch() == ' ')
		{
			fly_music();
			bird_y -= 4;
		}
}

在游戏模块.cpp程序文件中我们用到了rand(),srand()函数来生成随机数及种子,又用到了time()时钟。因此我们需要在Header.h中添加stdlibhtime.h。我们在UpdateWithInput()函数中用到了_getch()(用户输入且不被打印)函数,其头文件为conio.h应将也其添加到Header.h中

六.创建:主程序.cpp

#include"Header.h"
extern void startup(void);
extern void game_bg(void);
extern void UpdateWithoutInput(void);
extern void UpdateWithInput(void);
int main(void)
{
	startup();
	while (1)
	{
		game_bg();
		UpdateWithoutInput();
		UpdateWithInput();
	}

	return 0;
}

最后我们来看看添加的头文件
Header.h

#pragma once
#include
#include
#include
#include
#include
#pragma comment(lib,"winmm.lib")	

我的项目文件夹网盘地址
链接:https://pan.baidu.com/s/1QqCr5hBHTeKcxGqJffuIOA
提取码:wftf
复制这段内容后打开百度网盘手机App,操作更方便哦

你可能感兴趣的:(C)