我有一个行进中的声音文件,一旦发生了特定的事件,我就会播放它,但问题在于,当音量达到0时,该文件会在指定的时间内淡出,然后停止播放。这个项目是为桌面。
Sound marching = Gdx.audio.newSound(Gdx.files.internal("sounds/test.wav"));我在这方面的第一次尝试是通过计时器调度一个任务:
final long mId = marching.play(1f, 1f, 0);
for (float i = 1; i > 0; i -= 0.01) {
Timer.schedule(new Task() {
@Override
public void run() {
marching.setVolume(mId, i);
}
}, 0.3f);
}
marching.stop();然而,这似乎在marching#setVolume之前调用了marching#stop
我决定采用另一种方法:
float volume = 1;
final long mId = marching.play(volume, 1f, 0), startTime = TimeUtils .millis();
while (volume > 0) {
if (TimeUtils.millis() - startTime % 300 == 0) marching.setVolume(mId, volume -= 0.1);
}
marching.stop();我认为这会根据分配的时间减少音量,但它只会使程序冻结。
有没有一种简单的方法可以淡出SFX音频,或者设置频繁睡眠,这样我就可以反复降低音量?
谢谢。
发布于 2016-03-02 20:10:50
我认为最简单的方法是将其放入render方法中:
float FACTOR = 10; // The bigger the factor, the faster the fade-out will be
float mVolume = 1;
boolean mIsPlaying = true;
public void render(float delta) {
// ...
if (mIsPlaying) {
mVolume -= delta * FACTOR;
if (mVolume > 0) {
marching.setVolume(mId, mVolume);
}
else {
marching.stop(mId);
mIsPlaying = false;
}
}
// ...
}发布于 2016-03-02 21:59:52
第一个解决方案是错误的,我为你重写了它:
final long mId = marching.play(1f, 1f, 0);
Timer.schedule(new Task() {
@Override
public void run() {
for (float i = 1; i > 0; i -= 0.01)
{
marching.setVolume(mId, i);
if(i<=0)
marching.stop();
}
}
}, 0.3f);第二个解决方案冻结你的应用,因为你是在主线程中调用它,而不是在异步任务中!
但是,使用渲染任务并不是一个好主意。你应该从游戏循环任务中分离渲染任务。读一读:http://gameprogrammingpatterns.com/game-loop.html。你的游戏逻辑应该在所有机器上以相同的速度运行。不能受渲染问题/速度慢问题的限制。
发布于 2016-08-12 21:56:41
我发现这比使用循环要好得多。
我将MUSIC_FADE_STEP设置为0.01f (即每次通过时将音量调整1% )。
我根据需要调整fadeRate (以秒为单位)。0.01f可以很好地作为起点。
Timer.schedule(new Timer.Task() {
@Override
public void run() {
if (music.getVolume() >= MUSIC_FADE_STEP)
music.setVolume(music.getVolume()-MUSIC_FADE_STEP);
else {
music.stop();
this.cancel();
}
}
}, 0f, fadeRate); https://stackoverflow.com/questions/35744181
复制相似问题