09. 音符生成
在本章中,我们将实现音符的生成逻辑。
目标时间
我们首先需要计算一个音符的目标时间。 Sonolus.js 提供一个绑定方法:使用 Sonolus 提供的低级函数,将节拍直接转换为时间。
因为目标时间是每个音符实体的不变属性,并且是生成逻辑所需要的,所以我们应该在preprocess
期间计算一次,并将其存储在实体内存中:
export class Note extends Archetype {
// ...
targetTime = this.entityMemory(Number)
preprocess() {
this.targetTime = bpmChanges.at(this.import.beat).time
}
// ...
}
export class Note extends Archetype {
// ...
targetTime = this.entityMemory(Number)
preprocess() {
this.targetTime = bpmChanges.at(this.import.beat).time
}
// ...
}
生成时间
计算出目标时间后,假设我们希望音符提前1
秒生成并从上方掉落,以便让玩家有时间准备,我们可以计算生成时间。
和目标时间一样,生成时间也是每个音符实体的不变属性,是生成逻辑所需要的,我们应该在preprocess
时计算一次并将其存储在实体内存中:
export class Note extends Archetype {
// ...
spawnTime = this.entityMemory(Number)
preprocess() {
// ...
this.spawnTime = this.targetTime - 1
}
// ...
}
export class Note extends Archetype {
// ...
spawnTime = this.entityMemory(Number)
preprocess() {
// ...
this.spawnTime = this.targetTime - 1
}
// ...
}
生成逻辑
音符应按其生成时间的顺序生成,但我们还需要确保音符只会在初始化后生成。
一个简单的方法是直接用生成时间加上1000
(作为生成顺序) :
export class Note extends Archetype {
// ...
spawnOrder() {
return 1000 + this.spawnTime
}
// ...
}
export class Note extends Archetype {
// ...
spawnOrder() {
return 1000 + this.spawnTime
}
// ...
}
对于shouldSpawn
,逻辑是直接将当前时间与生成时间进行比较:
export class Note extends Archetype {
// ...
shouldSpawn() {
return time.now >= this.spawnTime
}
// ...
}
export class Note extends Archetype {
// ...
shouldSpawn() {
return time.now >= this.spawnTime
}
// ...
}