cocos2d-x萌新指南(二)——背景音乐、帧动画、sequence

DinS          Written on 2016/4/11

第二话 跋涉

“我们到了山脚,则见那山峻峭壁立,就是有一双敏捷的腿,也是无能为力。”

——《神曲》 炼狱篇3:46-48

上一话主要还是停留在分析范例,这一话起开始真正写代码。

如果一个游戏没有音乐那么做得再好体验也大打折扣,现在来给主界面加上背景音乐。要做到这一点非常简单,实际上只需要引入一个.h文件并加入一行代码即可。

(大图点这里)

加入的内容已经用红线标明,这再次体现了cocos2d-x的引擎作用:使用便捷。另外这里新建了一个文件夹专门放置音乐,文件摆放要有条理。因此在“”里面的文件名之前要加上/sounds否则程序会找不到文件。

那么加入的这一行代码是什么意思呢?->之前的不需要管,来看之后的。playBackgroundMusic()是一个函数,这个函数有两个参数,一个是文件地址,另一个true表示重复播放。

注意到我把visibleSize和origin删除了,不影响程序。

你问我从哪里知道这个函数和参数含义的?就不告诉你 。开玩笑的,实际上本系列教程的所有代码都是学习的结果,一开始上网找,但后来发现许多东西找不到,即使找到的90%的情况也不能直接解决问题。引擎开发者早已经预料到了这种情况,并且把cocos2d-x的相关功能代码放到了tests文件夹里面,如果需要什么效果可以直接去查看,并配有范例,非常直观。

只有音乐和图像还不够,游戏里没有动画就不叫游戏,现在来为月亮加一个发光动画,效果如下图(做gif略麻烦,脑补之 )

要实现一个效果可以有多种办法,哪种方法调用资源最少、运行最快就是最好算法,这里要介绍的是帧动画,肯定不是最好的办法,但是最直观易懂。

所谓帧动画,顾名思义就是准备好图像,将这些图像一帧一帧连续播放,这样视觉上看起来像在运动。这种现象叫视觉暂留。(众人:赶快直奔主题)

为了播放帧动画首先需要有素材,我使用ps制作了20张图片并放到了resource/moonglow文件夹里,方便调用。

要成功播放帧动画需要两个部分,先来看第一部分,如上所示。使用auto创建了一个对象moonglow,从Animation::可以看出这是一个动画类,然而跟之前sprite/label等不同这里create()里面没有填任何东西。其次是一大串结构相似的代码,从名字可以看出是将图像一帧一帧加入moonglow,有更简便的方法来做这项工作,请读者自行查找,这里列出这么一大串是因为这种写法最直观、最易懂。后面的两行代码的作用已经在注释里写明。顺便提一句养成写注释的好习惯,这样方便自己日后修改,也方便其他人看懂你的代码。

接下来看第二部分:

紧接第一部分我们写了一小段代码,而且应该注意到红框里面的内容,如果看了上一话则这部分应该已经很熟悉了,对,这里直接创建了一个精灵,其内容就是帧动画的第一帧,位置刚好摆放到背景月亮的地方。现在的问题就是上下几行代码是干什么用的。

先来看上面几行,auto创建了action对象,注意后面的是Animate不是Animation,如果问这两个类有什么区别那就是一个是动词一个是名词。 (跟没说一样 )仔细看会发现action的create()函数里面的参数是moonglow,就是我们刚才创建的帧动画。因此可以这么理解:Animation把帧动画一帧帧布置好装到了一个序列里,然后Animate使用这个序列创建了一个真正能够播放的动作。大概吧。不管如何现在已经把动作预备好了,还缺一个执行动作的指令,那就是最后一句runAction。执行runAction的对象是刚刚创建的loading精灵,至于为什么必须让这个精灵来执行runAction我就不知道了,我尝试过其他的会报错,这里就不求甚解会使用即可。

runAction()函数的参数需要一个动作,把这里的sequence改成action编译没有任何问题,但是达不到最终效果,因为我们需要月亮不停地闪烁,如果这里改成action就是执行一遍,效果是月亮逐渐变亮,然后突然回到原样,然后没有然后了。为什么会这样?因为我们的素材就是逐渐变亮,又因为设置了动画播放结束后返回第一帧,所以会突然变为原样。为了达到变亮变暗不断往复的效果,这里需要请出sequence。

sequence是一个序列,制定好要播放的动画后按照顺序播完一个再播一个。使用auto创建一个sequence,初始化中按顺序填入需要播放的动画。action就是刚才创建的动作,action->reverse()就是将action的帧反过来播放一遍,这样就达到了月亮变亮再变暗的效果,DelayTime的用处是延缓一定时间后再继续执行动画,这样月亮发光的整体视觉效果更好,最后的nullptr表明sequence结束。注意这里月亮总计只发光三次,同样有更简便的方法来执行永远重复动作,具体如何实现请自行查找。毕竟独立解决问题的能力是程序员的必备技能。

在创建好sequence后runAction(sequence)开始按顺序执行sequence里面的动画,这样最终效果就完成了。再把退出按钮的图片替换掉,主场景就完成了。

编程并不困难,要有信心。下一话我们将探讨更加困难的一些问题,涉及创建新场景、创景转化等,见《cocos2d-x萌新指南(三)——新建场景、场景转换》。