首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Libgdx如何让SFX淡出?

Libgdx如何让SFX淡出?
EN

Stack Overflow用户
提问于 2016-03-02 18:13:53
回答 3查看 1.1K关注 0票数 2

我有一个行进中的声音文件,一旦发生了特定的事件,我就会播放它,但问题在于,当音量达到0时,该文件会在指定的时间内淡出,然后停止播放。这个项目是为桌面。

代码语言:javascript
复制
Sound marching = Gdx.audio.newSound(Gdx.files.internal("sounds/test.wav"));

我在这方面的第一次尝试是通过计时器调度一个任务:

代码语言:javascript
复制
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

我决定采用另一种方法:

代码语言:javascript
复制
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音频,或者设置频繁睡眠,这样我就可以反复降低音量?

谢谢。

EN

回答 3

Stack Overflow用户

发布于 2016-03-02 20:10:50

我认为最简单的方法是将其放入render方法中:

代码语言:javascript
复制
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;
        }
    }
    // ...
}
票数 1
EN

Stack Overflow用户

发布于 2016-03-02 21:59:52

第一个解决方案是错误的,我为你重写了它:

代码语言:javascript
复制
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。你的游戏逻辑应该在所有机器上以相同的速度运行。不能受渲染问题/速度慢问题的限制。

票数 1
EN

Stack Overflow用户

发布于 2016-08-12 21:56:41

我发现这比使用循环要好得多。

我将MUSIC_FADE_STEP设置为0.01f (即每次通过时将音量调整1% )。

我根据需要调整fadeRate (以秒为单位)。0.01f可以很好地作为起点。

代码语言:javascript
复制
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); 
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35744181

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档