【发布时间】:2012-08-28 11:30:56
【问题描述】:
我正在制作一个 Android 游戏,我需要在玩家与游戏对象交互时实现无延迟音效。为简单起见,物体在屏幕上四处移动,玩家必须点击它们才能触发音效。我遇到的问题是,当玩家在短时间内点击许多物体时,每个音效之间都会有明显的延迟。例如,玩家点击对象 1,播放声音,点击对象 2,播放声音,然后一直播放,直到玩家点击对象 n,声音播放,但听起来比之前播放的音效有点延迟。
我尝试将我的 SoundPool 对象设置为从同一资源加载不同的声音,但它似乎没有多大作用。那么有没有一种方法可以让音效的每次迭代重叠甚至停止上一次音效的迭代以被新的音效替换而不会出现明显的声音延迟?以下是我的代码:
protected SoundPool mSoundPool;
protected boolean mLoaded;
protected int mBalloonPopStreams = 5;
protected int[] mSoundIds;
protected int mSoundIdx = 0;
protected void initializeMedia() {
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
mSoundPool = new SoundPool(mBalloonPopStreams, AudioManager.STREAM_MUSIC, 0);
mSoundIds = new int[mBalloonPopStreams];
for (int i = 0; i < mBalloonPopStreams; i++) {
mSoundIds[i] = mSoundPool.load(this, R.raw.sound_effect, 1);
}
mSoundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
@Override
public void onLoadComplete(SoundPool soundPool, int sampleId,
int status) {
mLoaded = true;
}
});
}
protected OnTouchListener mTouchEvent = new OnTouchListener() {
@Override
public boolean onTouch(View arg0, MotionEvent arg1) {
int action = arg1.getAction();
int actionCode = action & MotionEvent.ACTION_MASK;
int pointerId = action >> MotionEvent.ACTION_POINTER_ID_SHIFT;
int x;
int y;
x = (int)arg1.getX(pointerId);
y = (int)arg1.getY(pointerId);
if (actionCode == MotionEvent.ACTION_DOWN || actionCode == MotionEvent.ACTION_POINTER_DOWN) {
// Check if the player tapped a game object
playSound();
}
return true;
}
};
public void playSound() {
if (mLoaded) {
synchronized(mSoundPool) {
AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
float actualVolume = (float) audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
float maxVolume = (float) audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
float volume = actualVolume / maxVolume;
mSoundPool.play(mSoundIds[mSoundIdx], volume, volume, 1, 0, 1f);
mSoundIdx = ++mSoundIdx % mBalloonPopStreams;
}
}
}
总而言之,问题在于,假设要在 1 秒内播放 5 个“流行”声音。我听到爆裂声播放了 5 次,但它们被延迟并且与游戏中实际发生的情况不同步。这可能是对硬件的限制吗?如果不是,那么我是否错误地实现了我的代码?这个问题有哪些解决方法?
【问题讨论】: