Sonolus Wiki

18. 音效

在本章中,我们将为音符和舞台添加音效。

音效片段

就像皮肤精灵图一样,我们需要通过引用它们的名称,来声明我们想要访问哪些音效片段:

export const effect = defineEffect({
    clips: {
        stage: EffectClipName.Stage,
        perfect: EffectClipName.Perfect,
        great: EffectClipName.Great,
        good: EffectClipName.Good,
    },
})
export const effect = defineEffect({
    clips: {
        stage: EffectClipName.Stage,
        perfect: EffectClipName.Perfect,
        great: EffectClipName.Great,
        good: EffectClipName.Good,
    },
})

音符

要给判定添加音效,我们可以检查判定结果,然后调用正确的音效片段上的play

请注意, play有一个distance参数,如果音效片段在指定的这个时长之前播放过,它将阻止播放音效片段。这是为了防止快速连续播放同一片段并导致音效播放问题。一般来说, 0.02是一个很好的值。

export class Note extends Archetype {
    // ...
    touch() {
        // ...

        for (const touch of touches) {
            // ...

            switch (this.result.judgment) {
                case Judgment.Perfect:
                    effect.clips.perfect.play(0.02)
                    break
                case Judgment.Great:
                    effect.clips.great.play(0.02)
                    break
                case Judgment.Good:
                    effect.clips.good.play(0.02)
                    break
            }

            // ...
        }
    }

    // ...
}
export class Note extends Archetype {
    // ...
    touch() {
        // ...

        for (const touch of touches) {
            // ...

            switch (this.result.judgment) {
                case Judgment.Perfect:
                    effect.clips.perfect.play(0.02)
                    break
                case Judgment.Great:
                    effect.clips.great.play(0.02)
                    break
                case Judgment.Good:
                    effect.clips.good.play(0.02)
                    break
            }

            // ...
        }
    }

    // ...
}

舞台

由于我们已经有了对点击有反应的判定线,因此播放音效也很有意义。

但是,如果音符已经使用了该触摸数据,我们就不应该播放舞台音效了。

export class Stage extends Archetype {
    // ...

    touchOrder = 2
    touch() {
        for (const touch of touches) {
            if (!touch.started) continue
            if (isUsed(touch)) continue

            effect.clips.stage.play(0.02)
            return
        }
    }

    // ...
}
export class Stage extends Archetype {
    // ...

    touchOrder = 2
    touch() {
        for (const touch of touches) {
            if (!touch.started) continue
            if (isUsed(touch)) continue

            effect.clips.stage.play(0.02)
            return
        }
    }

    // ...
}