社会实践|南京农业大学信息科学技术学院卓越工程师班
社会实践正式宣告结束作品展Ⅰ

作者: 卓工班团队  提交时间:2018/9/6 19:58:18  浏览:162   [打印本篇文章]

优秀是将细节抠到极致

——南京农业大学信息科学技术学院2018年卓工班优秀作品展

京农业大学信息科学技术学院2018年卓工班总共参与答辩游戏作品46件,根据卓工班班长推荐,我们本次选择了王子聪同学的作品进行单独介绍。

卓工班班长陈锋评语:

“最后交作业的同学,也是完成度最高的同学,繁多的战机类型,恰如其分的攻击特效,细腻的攻击算法,独出心裁的难度安排,画面和代码质量俱佳。”

如陈锋所说,王子聪是我们啄木鸟工程师班答辩时最后提交作品的同学,慢工出细活,一件优秀的作品必然需要经过长时间的打磨。意料之中,他的作品向我们证明了这句话的正确性。意料之外,他实现的效果远超我们的期待。

根据王子聪同学的设计报告我们可以知道:该同学设计的是一款类似于手机游戏《全民飞机大战》的飞行射击游戏,游戏界面友好,操作方式简单却又不失难度。3关中,每关难度逐级递增,我方飞机设计了升级系统,而敌方飞机也种类繁多,玩家与不同的敌机战斗可享受发现并击毁新敌机的乐趣。

游戏设计了计分系统,击杀不同的敌机获得不同分数,游戏过程中会显示当前得分,游戏结束后会显示总分,可供玩家每局游戏结束后比较各局游戏得分。此外,部分敌机会掉落物品,玩家飞机拾取不同的物品可获得不同的效果,如我方飞机的升级系统即通过拾取升级物品实现。

游戏设计注重平衡性,通过普通敌机与boss的出现及其出现时机将游戏难度控制得较好,游戏可玩性较高,能够达到娱乐效果,为玩家舒缓压力,同时能够锻炼玩家的反应速度。

王子聪同学的作品不仅界面简洁,而且代码极其规范,细节抠到了极致。

一、在游戏的功能设计方面,王子聪设计了“我方飞机“具有以下4个属性,

1. 移动:由鼠标控制移动,鼠标位置决定飞机位置。

2. 发射子弹:子弹由飞机自动发射,无需控制

3. 拾取物品:飞机移动到物品所在位置可拾取该物品并获得该物品所提供的效果。

4. 升级:飞机拾取升级道具即可升级,游戏过程中共3个升级道具,每拾取一个升一级,每升一级飞机形态及飞机子弹均发生变化,子弹伤害增强。

“普通敌机“分为5个种类,如下:

1. 白色敌机:不会发射子弹,常速飞行。

2. 黄色敌机:能够直线向前发射子弹,常速飞行。

3. 大型机:飞机体型较大,能够直线向前、向两个前斜向45度共3个方向发射子弹,常速飞行。

4. 定向机:发射子弹朝向玩家所在方向,常速飞行。

5. 敢死队:不会发射子弹,但移动速度极快,以撞击玩家飞机来实现对玩家飞机造成伤害。

Boss飞机共有3个,如下:

1. 第一关boss:上下缓速移动,能够从两个不同位置直线向前,以及向两个前斜向45度发射子弹,并每数秒向玩家飞机发射一颗定向子弹。

2. 第二关boss:上下缓速移动,能够从两个不同位置直线向前,以及向两个前斜向45度发射子弹,并每数秒从2个方位向玩家飞机各发射一颗定向子弹,发射子弹频率均高于第一关boss。

3. 第三关boss:上下缓速移动,能够从两个不同位置直线向前,以及向两个前斜向30度、前斜向45度发射子弹,并每数秒向玩家飞机连续发射五颗定向子弹。

“物品”共有3种,如下:

1. 绿宝石:拾取后分数增加5。

2. 红宝石:拾取后分数增加10。

3. 生命道具:拾取后生命值增加20%。

4. 升级道具:拾取后可升级。

“子弹”共有2种,如下:

1. 我方子弹:能够对敌机造成伤害,升级后子弹形态改变且伤害提升。

2. 敌方子弹:能够对我方飞机造成伤害,不同类型敌机发射的子弹伤害不同。

我们剖析一下王子聪的功能设计描述,相比于其他同学设置了1种或2种敌机,他的敌机种类达到了5种,且每种敌机都具有独特的功能。

1.不会发射子弹的白色敌机


2.向前发射子弹的黄色敌机及其子弹


3.大型机及其子弹


4.定向机及其子弹


5.定向机子弹发射方位


定向机子弹朝玩家所在方向发射。

6.敢死队


敢死队移动速度快,但不会发射子弹。

每增加一个敌机,耗费的时间和精力都不是简单的加法,在编程时需要考虑到的问题也是成倍的增加。

BOSS机的设计上,王子聪在老师只要求一个BOSS的基础上锦上添花,为每一关安排了一个BOSS,而且3个BOSS的属性也各不相同。这就要求他需要为每一个BOSS机配置单独的类,并且设计不同的成员函数来实现它们的功能。BOSS机的增加也使程序的运行逻辑了变得更加复杂,花费的时间也会更多。我们还注意到他给BOSS机以及我方敌机都设置了血条,血条的随着游戏的进行动态变化,这同样增加程序的复杂性。


如上图所示,这是他游戏作品中的血条素材,他将所有的血条素材都放在一个图片中,这么做的好处就是当游戏运行时,血条一旦产生变化程序只需要读取一次文件。如果不这么做,那么每次血条变化后程序需要反复读取文件,这会对游戏窗口显示的效果造成不利影响,如频繁闪烁。程序优化的代价就是代码的复杂性提高,这对编程能力也提出了更高的要求,所以很少有同学能做到像他这样的将细节处理得如此之好。

类似的,我们也可以看到他将所有的子弹素材、飞机素材、道具素材等等也放在一个文件中,也就是说他为每一个相似的素材都做了这样的处理。我们还可以观察他的素材在图片中的摆放位置,一张图片中的各个素材的摆放是没有规律的,每个子弹的大小不一样,位置也不一样,这就意味着他需要在源代码中以像素级去区分每张图片中的各个素材,这样才能保证程序能从图片中读取出想要的素材。





在代码设计上,王子聪使用了面向对象的程序设计思想,将飞机、子弹、道具等封装为一个类,并从飞机类派生来三个子类,分别为我方飞机,敌方普通飞机,敌方boss。从子弹类派生来2个子类,分别为我方子弹与敌方子弹。游戏全过程的进展及不同对象的交互使用CControl类来实现。

我们选取王子聪在代码中的关于飞机类的描述:

//飞机类

class CPlane

{

public:

int x,y;//飞机位置

int MaxHP;//飞机生命值上限

int sizex,sizey;//飞机横、纵向宽度

int hp;//生命值

int score;//击杀得分

HBITMAP bitmap;//飞机显示

HBITMAP explode;//飞机死亡后爆炸显示

bool IsExist;//是否存活

int DeadState;//死亡爆炸后所处时间

int FireTime;//开火所处时间

CPlane(int xx,int yy,int health,int sc,int sx,int sy);

virtual ~CPlane(void);

virtual void DisplayHP();//显示血条

virtual void Fire();//发射子弹

virtual void Move()=0;//飞机移动

virtual bool DeadControl()=0;//根据飞机死亡后的状态判断是否删除飞机变量

virtual void Display(HDC &)=0;//飞机显示

};

这是所有飞机类的父类,每一个数据成员和成员函数的功能都注释清楚,且成员函数中采用了纯虚函数,如virtual void Move()=0,这样这个飞机类就成了一个抽象类,抽象类的主要作用是为其所组织的继承层次结构提供一个公共的基类,它刻划了公有行为的特征,其它类可以从它这里继承和实现接口,纯虚函数的实现由其具体的派生类来提供。

那为什么需要采用抽象类呢?因为飞机类在程序中并不会产生实例化的对象,产生对象的是由它派生出来的子类如我方飞机类,敌方飞机类等来实现的,因此飞机类一个不需要实例化的类,即虚基类。


从答辩的效果来看,他设计的游戏作品是令人惊艳的,这是王子聪对细节的极致追求才有的结果。当我们看到他的游戏运行界面,不能简单地认为他只是复刻一个手机端的游戏。尽管看起来游戏界面是和手机游戏几乎一样,可那只是表面上的相同。因为王子聪同学和其他的卓工班成员都一样,各位工程师只是采用了网络上已有的游戏素材作为程序的资源文件,但在代码设计阶段,程序的功能、功能的实现、实现的效果都是由工程师自己独立思考、独立完成,这个是没法借鉴他人的。

陈锋在文章开头的评语提到王子聪同学的作品具有“细腻的攻击算法,独出心裁的难度安排”,这两者是王子聪同学的亮点所在,却是很难感知到的亮点。实现了与没有实现对于普通的玩家是没有什么差别的,但是对于游戏的设计者来说,却要求他花费不少心思去实现。这就像是城市的建设一样,很多城市在地面以上,高楼林立,夜晚灯火通明,看起来一片繁华,但是在地面以下,排水设施的设计却大大缩水,一旦下起大雨,抗洪能力便经不起考验。王子聪设计出来的作品可以说是一个不仅地面建筑设计精美,而且地下排水能力强大的城市。

细腻的攻击算法,需要你打开程序的原文件细心阅读才能体会,难度安排如王子聪在设计报告中说明的那样:“游戏设计时注重平衡性,通过普通敌机与boss的出现及其出现时机将游戏难度控制得较好。游戏设计注重平衡性,不是有多少同学都能做到的,这种细节的考虑,可以使得游戏的可玩性更高,达到娱乐的效果,足以见得王子聪同学对细节的把握。

优秀是将细节抠到极致,一件优秀的作品必然意味着一位在背后细心雕琢的作者。“天上不会掉馅饼,努力奋斗才能梦想成真”。要想制作出一件可以让他人慢慢品味的作品,需要我们花费足够的耐心和精力,这也是王子聪同学最后才能提交作品的原因,他付出了耐心和精力,他也收获了喜悦和满足。