05. 音符绘制
在本章中,我们将实现音符原型的绘制逻辑。
声明
声明将使用的音符皮肤精灵:
export const skin = defineSkin({
sprites: {
// ...
note: SkinSpriteName.NoteHeadCyan,
},
})
export const skin = defineSkin({
sprites: {
// ...
note: SkinSpriteName.NoteHeadCyan,
},
})
屏幕缩放
与游玩模式不同,在预览模式中,我们已经修改了屏幕坐标系来使用不同的 X 与 Y 轴缩放。
为了正确绘制音符,我们需要提供长度和宽度缩放参数:
export const scaledScreen = {
wToH: panel.h / 20,
}
export const scaledScreen = {
wToH: panel.h / 20,
}
计算坐标
使用面板参数,我们可以计算在特定时间的坐标。
export const panel = {
// ...
getX(time: number) {
return Math.floor(time / this.h) * this.w
},
getY(time: number) {
return time % this.h
},
getPos(time: number) {
return new Vec(this.getX(time), this.getY(time))
},
}
export const panel = {
// ...
getX(time) {
return Math.floor(time / this.h) * this.w
},
getY(time) {
return time % this.h
},
getPos(time) {
return new Vec(this.getX(time), this.getY(time))
},
}
绘制
有了上述所有前提后,我们可以在正确的位置绘制正确大小的音符精灵:
export class Note extends Archetype {
// ...
render() {
const time = bpmChanges.at(this.import.beat).time
const pos = panel.getPos(time)
const layout = Rect.one.mul(options.noteSize).scale(1, scaledScreen.wToH).add(pos)
const z = 1000 - time
skin.sprites.note.draw(layout, z, 1)
}
}
export class Note extends Archetype {
// ...
render() {
const time = bpmChanges.at(this.import.beat).time
const pos = panel.getPos(time)
const layout = Rect.one.mul(options.noteSize).scale(1, scaledScreen.wToH).add(pos)
const z = 1000 - time
skin.sprites.note.draw(layout, z, 1)
}
}