android游戏开发添加背景音乐和音效--不需要用到service

时间:2021-05-09 19:46:42
最近在做一个android版的连连看小游戏,希望在游戏播放背景音乐以及音效,为此搜寻了相关资料,经过学习研究得出最终解决方案:MediaPlayer+SoundPool。
MediaPlayer 用来控制游戏背景音乐的播放。
SoundPool播放游戏音效,在初始化时加载游戏中用的所有音效文件,然后在游戏中进行播放,这样声音没有延迟,保证了游戏的性能。最初我还想让背景音乐也使用SoundPool进行播放,可是经过测试,总是不成功,而且在初始化时会很慢,不知道是不是因为SoundPool不适用较大的音乐文件?

特别要说的是,我在网上看到有些文章在讲解实现游戏背景音乐的播放时,说要使用service,本人很不赞同。可能是因为大多讲解service的教程都喜欢用音乐播放器的例子,所以很多人产生了一个误解,认为只要是播放音乐就要用到service。其实人家所说是开发一个音乐播放器,这个播放器需要在系统后台持续播放歌曲,而不管是用户停留在当前应用界面还是退出到了系统桌面,或是切换到了另一个应用的界面,总之意思是说要在系统后台进行播放,这时必须要用到service。而一个游戏的背景音乐仅仅需要在游戏运行的时候播放,而在返回到桌面或者进入其他应用使游戏的activity变为不可见时,都应该立即停止播放,根本没必要使用service。
有人可能说播放背景音乐应该在后台执行,不能影响程序的正常运行,这样说当然正确,但这仅需要开辟一个单独的线程来专门播放音乐就可以了,而经我测试,MediaPlayer和SoundPool本身都已经实现了在独立的线程中播放音乐,所以综上所述在游戏中播放背景音乐完全没必要使用service,那样完全是舍近求远,画蛇添足之举。只需直接使用MediaPlayer即可。请看我的代码:

这是一个实现游戏中播放声音的类,封装了MediaPlayer和SoundPool的使用细节,所有方法都定义为静态方法,在程序启动时先调用其init方法,然后在任何地方都可以非常方便的使用
package com.llkan.setup;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import com.llkan.R;

import android.content.Context;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.SoundPool;

/**
 * 声音控制类
 * @author wyf
 *
 */
public class SoundPlayer {

private static MediaPlayer music;
private static SoundPool soundPool;

private static boolean musicSt = true; //音乐开关
private static boolean soundSt = true; //音效开关
private static Context context;

private static final int[] musicId = {R.raw.bg,R.raw.bg1,R.raw.bg2,R.raw.bg3};
private static Map<Integer,Integer> soundMap; //音效资源id与加载过后的音源id的映射关系表

/**
 * 初始化方法
 * @param c
 */
public static void init(Context c)
{
context = c;

initMusic();

initSound();
}

//初始化音效播放器
private static void initSound()
{
soundPool = new SoundPool(10,AudioManager.STREAM_MUSIC,100);

soundMap = new HashMap<Integer,Integer>();
soundMap.put(R.raw.itemboom, soundPool.load(context, R.raw.itemboom, 1));
soundMap.put(R.raw.sel, soundPool.load(context, R.raw.sel, 1));
}

//初始化音乐播放器
private static void initMusic()
{
int r = new Random().nextInt(musicId.length);
music = MediaPlayer.create(context,musicId[r]);
music.setLooping(true);
}

/**
 * 播放音效
 * @param resId 音效资源id
 */
public static void playSound(int resId)
{
if(soundSt == false)
return;

Integer soundId = soundMap.get(resId);
if(soundId != null)
soundPool.play(soundId, 1, 1, 1, 0, 1);
}

/**
 * 暂停音乐
 */
public static void pauseMusic()
{
if(music.isPlaying())
music.pause();
}

/**
 * 播放音乐
 */
public static void startMusic()
{
if(musicSt)
music.start();
}

/**
 * 切换一首音乐并播放
 */
public static void changeAndPlayMusic()
{
if(music != null)
music.release();
initMusic();
startMusic();
}

/**
 * 获得音乐开关状态
 * @return
 */
public static boolean isMusicSt() {
return musicSt;
}

/**
 * 设置音乐开关
 * @param musicSt
 */
public static void setMusicSt(boolean musicSt) {
SoundPlayer.musicSt = musicSt;
if(musicSt)
music.start();
else
music.stop();
}

/**
 * 获得音效开关状态
 * @return
 */
public static boolean isSoundSt() {
return soundSt;
}

/**
 * 设置音效开关
 * @param soundSt
 */
public static void setSoundSt(boolean soundSt) {
SoundPlayer.soundSt = soundSt;
}

/**
 * 发出‘邦’的声音
 */
public static void boom()
{
playSound(R.raw.itemboom);
}
}

26 个解决方案

#1


该回复于2012-01-12 09:06:28被版主删除

#2


要怎么去调用咧?

#3


其实Android的Service就是*面的应用程序,否则,用Activity是一样的。我一直奇怪,有什么需求,必须用Service呢?答案是没有。

不用Service,一切功能都能实现。

#4


用Service显得牛B

#5


如何实现activty不可见时的音乐停止呢?比如我按了home键

#6


引用 5 楼  的回复:
如何实现activty不可见时的音乐停止呢?比如我按了home键


请问这个问题你解决了没

#7


protected void onResume()
{
// TODO Auto-generated method stub
super.onResume();
Music.play(this,R.raw.music);
}
protected void onDestroy()
{
// TODO Auto-generated method stub
super.onDestroy();
Music.stop(this);
}

#8


不用service请教一下
在几个Activity之间跳转怎么才能使背景音乐不重新播放

#9


顶顶,写的不错!

#10


高,实在是高,膜拜ing

#11


很不错 要是 有程序文件就更好了,自己不太好找音效!

#12


拿music来说,如果你写了一个music跑在你自己的进程中,那么,如果我觉得你的music写的很好,那么我打算用你的music player来播发音乐,如果不用service,请问,我改怎么和你交互呢?

#13


引用 8 楼 a19279741 的回复:
不用service请教一下
在几个Activity之间跳转怎么才能使背景音乐不重新播放


楼主说的是在游戏中,你在游戏中写多个activity? 找抽呢?

#14


android游戏开发添加背景音乐和音效--不需要用到service

引用 13 楼 sdlu1992 的回复:
引用 8 楼 a19279741 的回复:
不用service请教一下
在几个Activity之间跳转怎么才能使背景音乐不重新播放

楼主说的是在游戏中,你在游戏中写多个activity? 找抽呢?


至少得有两个页面吧,一个是主页面。可以设置音乐背景开或关,音效的开和关,然后进入主页面,保持背景音乐不间断。

#15


要是有界面就更好了,膜拜中

#16


引用 3 楼 pgmsoul 的回复:
其实Android的Service就是*面的应用程序,否则,用Activity是一样的。我一直奇怪,有什么需求,必须用Service呢?答案是没有。

不用Service,一切功能都能实现。

如果不让你显示音乐的activity 的界面 并且 后台播放,并且 还要监听 hook事件 还要监听电话 短信 FM 音频事件等等的问题 你说不用service 怎么解决呢?

#17


引用 12 楼 hvk687 的回复:
拿music来说,如果你写了一个music跑在你自己的进程中,那么,如果我觉得你的music写的很好,那么我打算用你的music player来播发音乐,如果不用service,请问,我改怎么和你交互呢?

我觉得逃亡神庙的音乐很好听,请大神给个代码让我用播放器播放。。。
游戏就是游戏,想要听就自己录或者下原声,哪还有这么无聊的需求。。。

#18


引用 16 楼 shen332401890 的回复:
引用 3 楼 pgmsoul 的回复:其实Android的Service就是*面的应用程序,否则,用Activity是一样的。我一直奇怪,有什么需求,必须用Service呢?答案是没有。

不用Service,一切功能都能实现。
如果不让你显示音乐的activity 的界面 并且 后台播放,并且 还要监听 hook事件 还要监听电话 短信 FM 音频事件等等的问题……


一个线程用于播放音乐,再开一个线程在此线程new 一个handle 用于控制线程,有问题么?

#19


没有界面切是没有问题的。不用service也可以监听电话等,只要注册监听就可以了。

#20


引用 19 楼 ameyume 的回复:
没有界面切是没有问题的。不用service也可以监听电话等,只要注册监听就可以了。


求解一个应用 切出了界面 还能运行吗? 如果没有service

#21


引用 20 楼 shen332401890 的回复:
引用 19 楼 ameyume 的回复:
没有界面切是没有问题的。不用service也可以监听电话等,只要注册监听就可以了。

求解一个应用 切出了界面 还能运行吗? 如果没有service

那时候就不运行了。
楼主要求切出后就停止播放了。

#22


引用 20 楼 shen332401890 的回复:
引用 19 楼 ameyume 的回复:没有界面切是没有问题的。不用service也可以监听电话等,只要注册监听就可以了。

求解一个应用 切出了界面 还能运行吗? 如果没有service


当然能运行啊, 线程是干啥的? 不过我一年多没摸Android开发了, 但是我记得是肯定行的.

#23


引用 13 楼 sdlu1992 的回复:
Quote: 引用 8 楼 a19279741 的回复:

不用service请教一下
在几个Activity之间跳转怎么才能使背景音乐不重新播放


楼主说的是在游戏中,你在游戏中写多个activity? 找抽呢?
为什么不能有多个activity呢?难道主activity跳转到游戏activity不需要关闭前一个activity吗?

#24


去纠结这个问题其实没有多大意义,音乐播放器不使用后台服务的,估计也就是你个人使用!如果市面上那些播放器都是一关掉activity就关掉的话,他们公司早就倒闭了!我们做技术方案的,为的就是解决人性的需求!

#25


引用 24 楼 kengric 的回复:
去纠结这个问题其实没有多大意义,音乐播放器不使用后台服务的,估计也就是你个人使用!如果市面上那些播放器都是一关掉activity就关掉的话,他们公司早就倒闭了!我们做技术方案的,为的就是解决人性的需求!

楼主讲的是在游戏中的音效和音乐添加,并不是说音乐播放器,音乐是随着游戏改变而改变的,游戏运行才是重点

#26


最近自己也在学,刚好做到了这个功能,根本没用到service

#1


该回复于2012-01-12 09:06:28被版主删除

#2


要怎么去调用咧?

#3


其实Android的Service就是*面的应用程序,否则,用Activity是一样的。我一直奇怪,有什么需求,必须用Service呢?答案是没有。

不用Service,一切功能都能实现。

#4


用Service显得牛B

#5


如何实现activty不可见时的音乐停止呢?比如我按了home键

#6


引用 5 楼  的回复:
如何实现activty不可见时的音乐停止呢?比如我按了home键


请问这个问题你解决了没

#7


protected void onResume()
{
// TODO Auto-generated method stub
super.onResume();
Music.play(this,R.raw.music);
}
protected void onDestroy()
{
// TODO Auto-generated method stub
super.onDestroy();
Music.stop(this);
}

#8


不用service请教一下
在几个Activity之间跳转怎么才能使背景音乐不重新播放

#9


顶顶,写的不错!

#10


高,实在是高,膜拜ing

#11


很不错 要是 有程序文件就更好了,自己不太好找音效!

#12


拿music来说,如果你写了一个music跑在你自己的进程中,那么,如果我觉得你的music写的很好,那么我打算用你的music player来播发音乐,如果不用service,请问,我改怎么和你交互呢?

#13


引用 8 楼 a19279741 的回复:
不用service请教一下
在几个Activity之间跳转怎么才能使背景音乐不重新播放


楼主说的是在游戏中,你在游戏中写多个activity? 找抽呢?

#14


android游戏开发添加背景音乐和音效--不需要用到service

引用 13 楼 sdlu1992 的回复:
引用 8 楼 a19279741 的回复:
不用service请教一下
在几个Activity之间跳转怎么才能使背景音乐不重新播放

楼主说的是在游戏中,你在游戏中写多个activity? 找抽呢?


至少得有两个页面吧,一个是主页面。可以设置音乐背景开或关,音效的开和关,然后进入主页面,保持背景音乐不间断。

#15


要是有界面就更好了,膜拜中

#16


引用 3 楼 pgmsoul 的回复:
其实Android的Service就是*面的应用程序,否则,用Activity是一样的。我一直奇怪,有什么需求,必须用Service呢?答案是没有。

不用Service,一切功能都能实现。

如果不让你显示音乐的activity 的界面 并且 后台播放,并且 还要监听 hook事件 还要监听电话 短信 FM 音频事件等等的问题 你说不用service 怎么解决呢?

#17


引用 12 楼 hvk687 的回复:
拿music来说,如果你写了一个music跑在你自己的进程中,那么,如果我觉得你的music写的很好,那么我打算用你的music player来播发音乐,如果不用service,请问,我改怎么和你交互呢?

我觉得逃亡神庙的音乐很好听,请大神给个代码让我用播放器播放。。。
游戏就是游戏,想要听就自己录或者下原声,哪还有这么无聊的需求。。。

#18


引用 16 楼 shen332401890 的回复:
引用 3 楼 pgmsoul 的回复:其实Android的Service就是*面的应用程序,否则,用Activity是一样的。我一直奇怪,有什么需求,必须用Service呢?答案是没有。

不用Service,一切功能都能实现。
如果不让你显示音乐的activity 的界面 并且 后台播放,并且 还要监听 hook事件 还要监听电话 短信 FM 音频事件等等的问题……


一个线程用于播放音乐,再开一个线程在此线程new 一个handle 用于控制线程,有问题么?

#19


没有界面切是没有问题的。不用service也可以监听电话等,只要注册监听就可以了。

#20


引用 19 楼 ameyume 的回复:
没有界面切是没有问题的。不用service也可以监听电话等,只要注册监听就可以了。


求解一个应用 切出了界面 还能运行吗? 如果没有service

#21


引用 20 楼 shen332401890 的回复:
引用 19 楼 ameyume 的回复:
没有界面切是没有问题的。不用service也可以监听电话等,只要注册监听就可以了。

求解一个应用 切出了界面 还能运行吗? 如果没有service

那时候就不运行了。
楼主要求切出后就停止播放了。

#22


引用 20 楼 shen332401890 的回复:
引用 19 楼 ameyume 的回复:没有界面切是没有问题的。不用service也可以监听电话等,只要注册监听就可以了。

求解一个应用 切出了界面 还能运行吗? 如果没有service


当然能运行啊, 线程是干啥的? 不过我一年多没摸Android开发了, 但是我记得是肯定行的.

#23


引用 13 楼 sdlu1992 的回复:
Quote: 引用 8 楼 a19279741 的回复:

不用service请教一下
在几个Activity之间跳转怎么才能使背景音乐不重新播放


楼主说的是在游戏中,你在游戏中写多个activity? 找抽呢?
为什么不能有多个activity呢?难道主activity跳转到游戏activity不需要关闭前一个activity吗?

#24


去纠结这个问题其实没有多大意义,音乐播放器不使用后台服务的,估计也就是你个人使用!如果市面上那些播放器都是一关掉activity就关掉的话,他们公司早就倒闭了!我们做技术方案的,为的就是解决人性的需求!

#25


引用 24 楼 kengric 的回复:
去纠结这个问题其实没有多大意义,音乐播放器不使用后台服务的,估计也就是你个人使用!如果市面上那些播放器都是一关掉activity就关掉的话,他们公司早就倒闭了!我们做技术方案的,为的就是解决人性的需求!

楼主讲的是在游戏中的音效和音乐添加,并不是说音乐播放器,音乐是随着游戏改变而改变的,游戏运行才是重点

#26


最近自己也在学,刚好做到了这个功能,根本没用到service