C 语言实验室 3:爆破彗星
本实验会给你一份说明书,它描述了一个程序,你需要运用你在前几章中学到的知识构建这个程序。
这个项目比你之前见识到的项目都要大,所以动手之前请阅读完全部内容,并给自己一点时间。不要担心会被难倒,这里没有新概念,你也可以接着往后读,回过头再来做这个实验。
我们还为你补充了一些设计上的细节,万事俱备,包你能写出代码。
但需要你去实现程序,我们不会提供任何代码或答案。
经典街机游戏——爆破彗星
很多人学 C 语言是为了写游戏,在本实验中,你将向史上最受欢迎、最长寿的电子游戏——《爆破彗星》——致敬!
任务:闪避彗星并向它们开炮
彗星是你在游戏中需要消灭的敌人,它们在屏幕中缓缓地漂浮、旋转,宇宙飞船不小心碰到它们就会一命呜呼。
欢迎登上“向量号”宇宙飞船!你将用键盘控制飞船在屏幕中移动。飞船装备了加农炮,你可以向面前的彗星开炮。
如果加农炮发出的炮弹击中了彗星,彗星就会炸成两瓣,玩家可以加 100 分。一颗彗星多次爆炸以后就会从屏幕中移除。
如果飞船撞到彗星,就会丢一条命。你一共有三条命,用完游戏就结束了。
Allegro
Allegro 是一款开源游戏开发库,用它创建的游戏代码可以在不同操作系统中编译运行。它支持 Windows、Linux 和 Mac OS,甚至还有手机。
安装 Allegro
可以在 Allegro Source Forge 网站上下载 Allegro 的源代码:
http://alleg.sourceforge.net/projects/alleg
可以从源代码仓库下载最新版本的代码,然后构建、安装 Allegro。无论你用的是什么操作系统,都可以在网站上找到对应的安装教程。
你需要 CMake
构建代码时你还需要安装一个叫
CMake 的工具。CMake 是一个构建工具,它简化了在不同操作系统中构建 C 程序的工作。如果你要安装 CMake ,可以访问 。 http://www.cmake.org
我们在这个实验中所提供的代码仅适用于 Allegro 5.0。如果你下载安装的是更新的版本,可能要稍作修改。
Allegro 能做什么?
Allegro 库将为你处理:
GUI
Allegro 将创建一个普通窗口来呈现你的游戏。这看起来没什么大不了,但不同操作系统创建窗口的方式天差地别,窗口与键盘鼠标交互的方式也不尽相同。
事件
每当按下一个键、移动一下鼠标或点击某个位置时,操作系统都会产生一个事件。事件其实就是一条数据,它告诉你计算机中发生了什么。事件在发送到程序之前会先进入一个队列。而 Allegro 简化了响应事件的过程,你能轻而易举地写出一段在用户按下空格(发射加农炮)时运行的代码。
定时器
你已经见识过了系统级定时器。Allegro 提供了一种简单的方式为你的游戏加上“心跳”。游戏每秒钟会“心跳”好几次以确保显示能够持续更新。通过定时器,你就能创建一个按固定帧率(FPS)刷新屏幕的程序,比如每秒 60 帧。
图形缓冲
为了让你的游戏流畅运行,Allgero 使用了双缓冲。双缓冲是一种游戏开发技术,它允许你先把图片缓存起来,然后再把它们显示到屏幕上,这样就能一次显示完整的一帧动画,游戏就更流畅了。
图形和变换
Allegro 自带了一组图形原语,你可以用它们绘制直线、曲线、文本、实心图形和图片。如果你安装了 OpenGL 显卡驱动,还能绘制三维图形。除此之外,Allegro 还支持变换,即在屏幕上旋转、平移、拉伸图形,这样你就能创建出逼真的宇宙飞船,并且让彗星在屏幕中辗转腾挪。
声音
Allegro 有一个完整的声音库,有了它你就可以在游戏中加入声音。
构建游戏
你需要想好源代码按照什么方式来组织。绝大多数 C 程序员会把代码分成好几个源文件,这样不但能更快地重新编译游戏,而且可以一次处理更少的代码。分离代码让整个过程变得清晰明了。
分离代码的方法有很多,其中一种是为每个在游戏中显示的元素分别创建一个源文件:
宇宙飞船
当你要在屏幕中控制很多物体时,应该为每个物体创建一个结构。宇宙飞船的结构如下:
飞船的外形
如果把代码设为以原点(稍后我们会讲)为参照绘制图形,就可以用以下代码画出飞船。
变量
s 是一个指向 Spaceship 结构的指针,我们把飞船漆成绿色。
碰撞
飞船撞到彗星会立刻阵亡,玩家会少了一条命。飞船在创建后的五秒不检查碰撞,新飞船出现在屏幕的正中央。
飞船行为
游戏开始时飞船出现在屏幕的正中央。你可以让飞船响应键盘按键,在屏幕上移动:
不要让飞船加速得太快,最好不要超过每秒几百像素。飞船只能前进不能后退。
读取按键
当你收到了一个事件,需要判断它是不是按键。可以通过读取它的类型来判断。
炮弹
小样,让你尝尝炮弹的滋味!飞船上的加农炮可以发出炮弹,你的任务是画出弹道。下面是炮弹的结构:
typedef struct { float sx; float sy; float heading; float speed; int gone; ALLEGRO_COLOR color;} Blast;
弹道
弹道是一条虚线,如果玩家射得很快,弹道就会密集起来,虚线就变成了实线,看起来就像加大了火力。
炮弹行为
不像游戏中的其他物体,炮弹从屏幕上消失以后不会再出现,也就是说你需要写一些创建炮弹和销毁炮弹的代码。飞船朝哪个方向飞炮弹就顺着哪个方向沿直线射出。炮弹的速率恒定,比如是飞船最快移动速度的三倍。被炮弹击中的彗星会一分为二。
彗星
彗星结构如下:
彗星的外形
下面这段代码以原点为参照画出彗星:
al_draw_line(-20, 20, -25, 5, a->color, 2.0f);al_draw_line(-25, 5, -25, -10, a->color, 2.0f);al_draw_line(-25, -10, -5, -10, a->color, 2.0f);al_draw_line(-5, -10, -10, -20, a->color, 2.0f);al_draw_line(-10, -20, 5, -20, a->color, 2.0f);al_draw_line(5, -20, 20, -10, a->color, 2.0f);al_draw_line(20, -10, 20, -5, a->color, 2.0f);al_draw_line(20, -5, 0, 0, a->color, 2.0f);al_draw_line(0, 0, 20, 10, a->color, 2.0f);al_draw_line(20, 10, 10, 20, a->color, 2.0f);al_draw_line(10, 20, 0, 15, a->color, 2.0f);al_draw_line(0, 15, -20, 20, a->color, 2.0f);
彗星
彗星在屏幕中沿直线移动,并绕着中心不断旋转。如果彗星从屏幕一侧飞出,马上会在屏幕另一侧出现。
命中彗星
如果加农炮发出的炮弹打中彗星,彗星就马上分成两瓣,每一瓣的大小是原来的二分之一。多次命中后彗星就会从屏幕上消失。每次命中彗星,玩家可以加 100 分。你认为应该用哪种数据结构保存屏幕上的彗星,一个很大的数组还是链表?
游戏状态
你还需要在屏幕上显示一些东西:玩家还剩几条命和当前得分。命用完以后,你需要友好地在屏幕的中央显示“游戏结束!”四个大字。
用“变换”移动物体
你要让物体在屏幕上“动起来”。飞船需要飞行,彗星需要旋转、漂移和变换大小。旋转、平移和伸缩操作需要很多数学知识,为此 Allegro 内置了一批“变换”函数。
你在绘制物体时只需要以原点为参照画出它就行了。原点位于屏幕的左上角,坐标为(0, 0),横着的是 X 轴,竖着的是 Y 轴。假设你要绘制飞船,可以先用变换函数把原点移动到飞船将在屏幕中出现的位置,然后根据飞船的旋转角度旋转原点,最后在原点处画出飞船即可。
可以像这样在屏幕上绘制飞船:
void draw_ship(Spaceship* s){ ALLEGRO_TRANSFORM transform; al_identity_transform(&transform); al_rotate_transform(&transform, DEGREES(s->heading)); al_translate_transform(&transform, s->sx, s->sy); al_use_transform(&transform); al_draw_line(-8, 9, 0, -11, s->color, 3.0f); al_draw_line(0, -11, 8, 9, s->color, 3.0f); al_draw_line(-6, 4, -1, 4, s->color, 3.0f); al_draw_line(6, 4, 1, 4, s->color, 3.0f);}
《爆破彗星》下线
全部写完之后,你就可以重温《爆破彗星》这款经典!
出山……
送君千里终须一别!
虽然我们舍不得你,但又不得不和你说再见。正所谓“纸上得来终觉浅,绝知此事要躬行”。我们在本书的附录中放了一些“美味佳肴”和一个建议阅读列表,等你看完以后就可以出山把所有知识运用到实践中。我们希望得知你的进展,欢迎在 Head First 实验室的网站 上给我们留言,让我们知道 C 语言对你的帮助有多大!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论