【目标】:制作一个简单的音乐炫台式的游戏
一、游戏概念
游戏的设想是来自于一个简单的FLASH游戏。我这边基本做完了以后发现android平台也有一款类似的游戏《音乐炫台》。其界面和扫雷类似,是一个方格阵,被选中的格子会随着节拍发出声响,并且发出声响时会有一定的特效来显示。玩家可以通过选中不同的格子来组合成各种音乐。
做这个游戏的目的有两个:一是学习音效的实现,二是学习特效的实现。
二、游戏机制的具体研究
游戏界面如下:
如上所述,这里是一个10*10的方格阵,方格未选中时为灰色,选中为白色。用户点击一个方格可以将其选中或反选,支持通过滑动进行多选。
游戏开始后,会扫描第一列,然后隔500ms扫描第二列,依次类推,被扫描的列上白色的格子会发出声响,不同的行上的格子发出的声响是不同的,但是相同的行上发出的声音是相同的。在发出声响的同时,该格子会产生一个cocos2D演示程序中 explodingRing 的特效。
三、声音
1、格式的选择
这个游戏面临的第一个问题就是如何准备音频资源。我们先看看cocos2d-x支持哪些“音效”格式(这里强调音效,因为背景音乐貌似还不一样):
android:MP3、WAV、OGG
WIN32:MP3、WAV、MID
IOS:MP3、CAF(未测试)
需要注意的是WIN32上并不支持 OGG 格式,我试过一次,虽然不会crash,但完全放不出来声音。虽然在ANDROID上OGG格式最优,不过最终我这里选择的是全部使用 MP3格式,方便在WIN32上调试,当然最后转成 OGG格式也并不麻烦。
2、音频文件的制作
我们的目标只是要制作10个300ms左右的单音符乐曲。不太清楚真正游戏开发使用什么工具,我这里使用的是 Band in a Box 2012。
进入后感觉相当专业,幸好小时候学过琴还有点概念。这里只说明和本次目标相关的部分:
对于我们的目标而言,乐曲长度只需要一节,不需要循环,伴奏什么的也完全不需要,所以点击伴奏风格,取消 “style is enabled”,然后将乐曲长度设置为1,循环次数设为1,取消循环的勾选,节奏可以根据需要调整,我貌似设置的是300。
然后从 edit -> set Time Signature 来设置节拍,这里求短,设置成1/4拍即可。
接着点击那个音符按钮,编辑当前小节(事实上也是仅存的唯一一小节了),界面如下。
首先点击进入编辑模式,此时,点击五线谱上任意位置,都会在该位置上出现对应音符,如果点错了,还可以拖动该音符。不过默认长度是满长度的,可以通过右键菜单中 Edit Node 来改变 Duration。
编辑完成后可以点击播放试听一下,如果OK的话,就可以点 FILE 下的 Make Standard MIDI File,或者直接F6,来输出成一个 MIDI文件,注意我们这里只需要一个音节,所以在确认输出时,在 options 中,将 Include 2 bar lead-in in MIDI file 给去掉。
3、音频文件的转换
得到的MID文件,在android平台是不好用的,建议转换成OGG或者MP3。这里使用 MID to MP3 这样一款软件首先转为MP3格式。
得到这样一个MP3格式之后,就可以使用其他工具来进行任意转换了,这里强烈推荐 魔影工厂。好用不收费,简直霸道。唯一需要说明的是,在转换的时候是可以指定音量的放大倍数的,如果源音效的声音不够大,那么现在补救也来得及。
4、音频文件的播放
在cocos中,播放音效比较的简单,首先将该音频文件放到资源文件夹下。然后在代码中调用
CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect(m_SoundFile);
依赖的头文件是 SimpleAudioEngine.h。参数是文件名称,可以是绝对路径(如果不放在默认的资源文件夹下这种比较有用)。另外还有一个两参数的版本,可以设定是否一直循环播放。
如果想要进行一定程度的优化,还可以预先加载这些音效文件:
void SoundBlock::initSoundPool() {
for ( int i = 0; i < 10; i ++ )
CocosDenshion::SimpleAudioEngine::sharedEngine()->preloadEffect(SOUND_FILES[i]);
}
当然在结束的时候不要忘记释放这些资源:
void SoundBlock::freeSoundPool() {
for ( int i = 0; i < 10; i ++ )
CocosDenshion::SimpleAudioEngine::sharedEngine()->unloadEffect(SOUND_FILES[i]);
}
实际上这个 SimpleAudioEngine 还是比较弱的,支持的功能不多。如果是在 IOS上的话,还可以使用 CDAudioManager,那个要强大不少。
四、粒子特效
音效已经准备好,现在开始准备视觉上的特效。这里打算使用简单的粒子特效。
1、基本的粒子特效
cocos中已经准备了几种常用的粒子特效,可以参考 CCParticleExamples.cpp。例如CCParticleGalaxy之类的。使用方法如下:
emitter = CCParticleGalaxy::create();
emitter->retain(); //注意这里的retain
emitter->setTexture(CCTextureCache::sharedTextureCache()->addImage("fire.png"));
emitter->setPosition(ccp(m_Size/2, m_Size/2));
emitter->setDuration(0.3f);
emitter->setAutoRemoveOnFinish(true);
addChild(emitter, 10);
2、额外篇:水波式网格动作
除了粒子特效以外,网格动作也可以实现很多特效效果。这个可以参考 CCActionTiledGrid.cpp。网格动作实际上也是一种动作,可以通过 runAction来执行。例如如果要使用水波效果的话,就可以采用 CCWavesTiles3D 来实现。
3、exploding Ring
以我目前的理解,粒子效果的关键时机上在于对 CCParticleSystem 中的大量参数的调节,cocos为了方便程序员,除了可以在代码中逐个指定之外,还可以通过编写list来指定各个参数值。我这里的特效XML是直接COPY的 TESTCPP工程下的 ExplodingRing.plist。在代码中则是按照如下方式指定:
//播放特效
emitter = new CCParticleSystemQuad();
emitter->initWithFile("ExplodingRing.plist");
emitter->setPosition(ccp(m_Size/2, m_Size/2));
emitter->setAutoRemoveOnFinish(true);
addChild(emitter, 10);
五、代码实现
搞定了上面的两步,剩下的都很简单,见源码。