20. 倍速
在本章中,我们将为音符添加倍速。
倍速
倍速是很多节奏类游戏的共同特征,它的另一个名字是 soflan。我们将实现倍速,更具体地说,倍速可以让整个游戏减速/加速。
由于倍速很流行,Sonolus 也提供了方便的函数来处理倍速。
倍速变化
与 BPM 变化类似,倍速变化也有一个特殊的原型名称,以及倍速值的特殊原型数据名称。让我们在测试关卡中添加一个倍速变化列表:
export const data: LevelData = {
// ...
entities: [
// ...
...chart.timeScales.map(({ beat, timeScale }) => ({
archetype: EngineArchetypeName.TimeScaleChange,
data: [
{
name: EngineArchetypeDataName.Beat,
value: beat,
},
{
name: EngineArchetypeDataName.TimeScale,
value: timeScale,
},
],
})),
// ...
],
}
export const data = {
// ...
entities: [
// ...
...chart.timeScales.map(({ beat, timeScale }) => ({
archetype: EngineArchetypeName.TimeScaleChange,
data: [
{
name: EngineArchetypeDataName.Beat,
value: beat,
},
{
name: EngineArchetypeDataName.TimeScale,
value: timeScale,
},
],
})),
// ...
],
}
音符
要为音符实现倍速,我们只需要将所有与渲染相关的逻辑更改为使用倍速时间。
请注意,我们没有更改与输入相关的逻辑,因为即使开启倍速,也应保持原始的视觉特征,不应影响输入的处理方式。
export class Note extends Archetype {
// ...
preprocess() {
// ...
this.visualTime.max = timeScaleChanges.at(this.targetTime).scaledTime
// ...
}
// ...
shouldSpawn() {
return time.scaled >= this.spawnTime
}
// ...
updateParallel() {
// ...
const y = Math.unlerp(this.visualTime.min, this.visualTime.max, time.scaled)
// ...
}
}
export class Note extends Archetype {
// ...
preprocess() {
// ...
this.visualTime.max = timeScaleChanges.at(this.targetTime).scaledTime
// ...
}
// ...
shouldSpawn() {
return time.scaled >= this.spawnTime
}
// ...
updateParallel() {
// ...
const y = Math.unlerp(this.visualTime.min, this.visualTime.max, time.scaled)
// ...
}
}