【广而告之】山寨腾讯“爱消除”游戏已经正式入驻GitHub,项目地址是:https://github.com/3125788/CrazyLink
欢迎广大寨友一起来完善这个游戏。
按照声音的功能不同,我们将声音效果分为音乐和音效两个部分。比如较长的音乐可以作为游戏的背景音乐,而一些与动作配合的短小的声音我们则称之为音效。
音乐与音效看起来相同,其实却采用了不同的技术。
1、背景音乐
背景音乐通常播放时间较长,且文件体积较大,这类资源如果放在内存中,会给系统造成很大的负担。另外,背景音乐的播放,与音效相比,速度可以稍微慢一点,因此没有必要放在内存中。
Android中播放背景音乐通常使用MediaPlayer类。播放背景音乐的代码如下:
@Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
if(mp==null){
// R.raw.mmp是资源文件,MP3格式的
mp = MediaPlayer.create(this, R.raw.s_background);
mp.setLooping(true);
mp.start();
}
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
mGLSurfaceView.onPause();
mp.pause();
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
mp.stop();
}
2、动作音效
动作音效的特点是快和短。因此这类时间短但是要求反应迅速的音效,就不能用播放较长时间音乐的播放技术了。通常我们会采用SoundPool来实现。
SoundPool用于管理和播放应用程序的声音资源,给类将声音文件加载到内存中。处于性能考虑,一般不要将大于7秒的声音文件用此技术来播放。
详细代码见package elong.CrazyLink.Core 中的Sound类
public class Sound {
public enum E_SOUND
{
SLIDE,
FILL,
DISAPPEAR3,
DISAPPEAR4,
DISAPPEAR5,
READYGO,
TIMEOVER,
SUPER,
COOL,
BOMB,
MONSTER,
}
//音效的音量
int streamVolume;
//定义SoundPool 对象
public SoundPool mSoundPool;
//定义HASH表
public HashMap<Integer, Integer> mSoundPoolMap;
Context mContext;
public Sound(Context c){
mContext = c;
InitSounds();
}
private void InitSounds()
{
System.out.println("InitSounds");
initSounds();
}
private void initSounds()
{
//初始化soundPool 对象,第一个参数是允许有多少个声音流同时播放,第2个参数是声音类型,第三个参数是声音的品质
mSoundPool = new SoundPool(100, AudioManager.STREAM_MUSIC, 100);
//初始化HASH表
mSoundPoolMap = new HashMap<Integer, Integer>();
//获得声音设备和设备音量
AudioManager mgr = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE);
streamVolume = mgr.getStreamVolume(AudioManager.STREAM_MUSIC);
loadSfx(R.raw.s_readygo, E_SOUND.READYGO.ordinal());
loadSfx(R.raw.s_timeover, E_SOUND.TIMEOVER.ordinal());
loadSfx(R.raw.s_bomb, E_SOUND.BOMB.ordinal());
loadSfx(R.raw.s_cool, E_SOUND.COOL.ordinal());
loadSfx(R.raw.s_disappear3, E_SOUND.DISAPPEAR3.ordinal());
loadSfx(R.raw.s_disappear4, E_SOUND.DISAPPEAR4.ordinal());
loadSfx(R.raw.s_disappear5, E_SOUND.DISAPPEAR5.ordinal());
loadSfx(R.raw.s_slide, E_SOUND.SLIDE.ordinal());
loadSfx(R.raw.s_super, E_SOUND.SUPER.ordinal());
loadSfx(R.raw.s_fill, E_SOUND.FILL.ordinal());
loadSfx(R.raw.s_monster, E_SOUND.MONSTER.ordinal());
}
//加载音效资源
private void loadSfx(int raw, int id) {
//把资源中的音效加载到指定的ID(播放的时候就对应到这个ID播放就行了)
mSoundPoolMap.put(id, mSoundPool.load(mContext, raw, id));
}
//sound:要播放的音效的ID, loop:循环次数
private void play(E_SOUND sound, int loop) {
int id = sound.ordinal();
mSoundPool.play(mSoundPoolMap.get(id), streamVolume, streamVolume, 1, loop, 1f);
}
void play(E_SOUND sound)
{
play(sound, 0);
}
}
最后,贴一张优化后的效果图出来: