这个小游戏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
通过图片来获取我们需要的参数。
界面尺寸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,将用到的音乐资源存放到这里
这里我们用到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中定义的变量,利用其外部链接及文件作用域,在这里我们要做一下引用试声明。同理对音乐函数也进行引用。
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中添加stdlibh,time.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,操作更方便哦