Sonolus Wiki

09. 音符生成

在本章中,我们将实现音符的生成逻辑。

目标时间

我们首先需要计算一个音符的目标时间。 Sonolus.js 提供一个绑定方法:使用 Sonolus 提供的低级函数,将节拍直接转换为时间。

因为目标时间是每个音符实体的不变属性,并且是生成逻辑所需要的,所以我们应该在preprocess期间计算一次,并将其存储在实体内存中:

export class Note extends Archetype {
    // ...

    targetTime = this.entityMemory(Number)

    preprocess() {
        this.targetTime = bpmChanges.at(this.data.beat).time
    }

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

    targetTime = this.entityMemory(Number)

    preprocess() {
        this.targetTime = bpmChanges.at(this.data.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
    }

    // ...
}