Sonolus Wiki

04. 音符与面板数量

在本章中,我们将设置音符原型并实现计算面板数量。

音符原型

让我们首先设置音符原型:

export class Note extends Archetype {}
export class Note extends Archetype {}
export const archetypes = defineArchetypes({
    // ...
    Note,
})
export const archetypes = defineArchetypes({
    // ...
    Note,
})

持续时间

如果我们知道了持续时间,我们就可以用它来计算面板数量。

那么我们如何获取持续时间呢?一个简单的方法就是使用一个变量存储一个关卡的时长,并在我们访问音符时更新它。

让我们使用 Preview Data 区块声明它:

export const chart = previewData({
    duration: Number,
})
export const chart = previewData({
    duration: Number,
})

更新持续时间

为了计算音符时间,我们需要知道它的节拍。我们可以像游玩模式一样声明它:

export class Note extends Archetype {
    import = this.defineImport({
        beat: { name: EngineArchetypeDataName.Beat, type: Number },
    })
}
export class Note extends Archetype {
    import = this.defineImport({
        beat: { name: EngineArchetypeDataName.Beat, type: Number },
    })
}

在音符原型的 preprocess 回调函数中,如果音符时间更大,我们将更新持续时间:

export class Note extends Archetype {
    // ...

    preprocess() {
        chart.duration = Math.max(chart.duration, bpmChanges.at(this.import.beat).time)
    }
}
export class Note extends Archetype {
    // ...

    preprocess() {
        chart.duration = Math.max(chart.duration, bpmChanges.at(this.import.beat).time)
    }
}

面板数量

现在我们可以根据持续时间计算并更新面板数量:

export const panel = {
    // ...

    get count() {
        return Math.ceil(chart.duration / this.h)
    },
}
export const panel = {
    // ...

    get count() {
        return Math.ceil(chart.duration / this.h)
    },
}

画布

最后,我们需要在所有音符都更新持续时间完成后,确保计算画布大小代码的正常执行。

我们可以将代码移动到舞台原型的 preprocess 回调函数并给予其一个更高的顺序:

export class Stage extends Archetype {
    preprocessOrder = 1
    preprocess() {
        canvas.set({
            scroll: Scroll.LeftToRight,
            size: (panel.count * panel.w * screen.h) / 20,
        })
    }

    // ...
}
export class Stage extends Archetype {
    preprocessOrder = 1
    preprocess() {
        canvas.set({
            scroll: Scroll.LeftToRight,
            size: (panel.count * panel.w * screen.h) / 20,
        })
    }

    // ...
}