C语言课程设计-基于EasyX的飞机大战游戏

EasyX是基于C++的图形库,使用EasyX学习C语言,可以摆脱黑洞洞的控制台,快速做出有意思的项目。编程是有趣的,但是传统的C语言教学,教学的目的却是考试与刷题。于是我写了一个飞机大战的游戏,可以作为C语言的课程设计。完整的代码接近1000行,编写的过程也比较复杂。我带过一些学生的实训课,授课过程录屏了,放在B站上了。如果列位看官老爷感兴趣,再考虑下整理文档教程吧。

C课程设计-基于EasyX的飞机大战游戏

虽然名义上是C语言的游戏,本质上,只是借着游戏的名头,产生了一些需求,然后用C语言解决问题而已。游戏的耐玩性一般,重点在于解决思路。我主要解决的问题有:

0、素材的处理

游戏中用到的所有素材都是在爱给网上下载。部分图片使用3D画图的神器选择功能,进行抠图,得到png图片。过程略。
在这里插入图片描述

1、透明贴图

使用png格式的图片,图片需要处理产生透明通道。easyX默认的putimage函数,会有黑色背景。
在这里插入图片描述
我查到的一些解决办法是,使用MASK,用类似于掩码的机制。而采用alpha透明贴图,会更加简单一些。
实现的效果:
在这里插入图片描述

2、获取按键输入

调用的函数为GetAsyncKeyState。相比于getchar函数,使用起来更加方便,也不会阻塞程序。

3、解决easyX动画造成的画面闪烁问题

以绿色的小球在黑色的背景移动为例,这是因为每次画一个小球,不论是绘制新的小球,还是绘制背景色的小球,对于小球当前位置和下个位置重叠的部分,会被重复操作,看上去是绿色→黑色→绿色。如下图所示。先是绘制了绿球(A区域),延时后绘制黑球遮挡住刚才绘制的绿球(B区域),改变小球的坐标后,在更新的坐标在绘制绿球(C区域)。
在这里插入图片描述
重叠的部分绿色和黑色交替出现(D区域),便会有闪烁的现象。EasyX提供了BeginBatchDraw(),FlushBatchDraw(),EndBatchDraw()批量绘图函数处理画面闪烁的问题。

4、动态控制刷新率,显示FPS

一些基于EasyX的游戏,每一轮的休眠的时间是固定的,但这种做法是不合理的。因为不同的电脑有不同的运行速度,每一轮执行所消耗的时间也不相同,所以一成不变的休眠时间会造成游戏在不同电脑上,或者处理不同业务逻辑的时候,游戏速度不同。
此处使用了动态控制刷新率的方法,获取某一轮已经运行的时间,然后休眠剩余的时间。例如将FPS控制在70左右,则每一轮休眠13ms。如果这一列的其它任务已经执行了5ms,那么需要休眠8ms。如果一起任务只用掉了3ms,那么休眠10ms。

5、敌机的运动路线,与画一条直线

此处画一条直线并非调用line函数,而是敌机运行轨迹的一种。我设计的敌机运行轨迹如下:
在这里插入图片描述
游戏中有3种UFO,每种UFO都有不同的移动方式,大型UFO缓慢向前,一段时间后再退回去;中型UFO向前蛇形走位,遇边折返;小型UFO快速撞向玩家飞机。
所以小UFO的实际路线是,根据自身出生的位置与当前我方所在的位置,画一条直线,然后沿着直线前进。

6、链表的使用

不同的飞行器都在发射子弹,跑出屏幕与击中敌人的子弹都会消失。每个子弹都有自身的属性,如坐标,速度,伤害,存在标记等。
子弹需要使用结构体来储存。如果使用结构体数组,数组长度是固定的,且从数组中删除一个元素很麻烦。因此,子弹理想的保存方式就是链表。
游戏中共有3个链表,实现了指定链表尾插,按值删除的功能。为不同的飞行器的子弹设置了不同的速度,实现了多种子弹的效果。

7、判断点是否在三角形内

这是一个很棒的算法。我方飞机的形象是三角形的纸飞机,我方飞机是否被击中,其实就是判断敌机发射的子弹是否在我方飞机的三角形内。
如果我方是个矩形,那么多几个判断语句,总能判断是否被击中;如果我方是个圆形,计算距离,也能判断是否被击中。但是,我方是个三角形,就必须采用特殊的算法。仍然采用矩形判断的方法,会出现明明子弹没有击中我方飞机,飞机却掉血的情况,用户体验很差。
在这里插入图片描述
本游戏采用了向量计算的方法,能够以很小的计算量,判断出点是否在三角形内。主要算法参考了这篇博客

8、插入音效

应用了windows的API,函数为mciSendString,实现背景音乐,射击音效与敌机消失音效。

具体的设计与讲解过程请移步B站视频,配套的笔记与源码,左侧扫描关注公众号yummy说电子,发送“飞机大战”

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇

)">
下一篇>>