Sonolus Wiki

17. Life

In this chapter, we will set up life and secondary metric UI.

Archetype Life Increment

For each archetype, we can reward or punish player for hitting a judgment type.

In our engine, we are going to reward player for hitting a Perfect note by 10 life, and punish player for hitting a Miss note by 100 life.

export class Note extends Archetype {
    // ...

    globalPreprocess() {
        // ...

        this.life.set({
            perfect: 10,
            great: 0,
            good: 0,
            miss: -100,
        })
    }

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

    globalPreprocess() {
        // ...

        this.life.set({
            perfect: 10,
            great: 0,
            good: 0,
            miss: -100,
        })
    }

    // ...
}

Consecutive Judgment Type Life Increment

Similar to score, we can also reward or punish player for hitting consecutive judgment type or above, regardless of archetype.

In our engine, we are going to reward player for hitting 10 consecutive Perfects by 50 life.

export class Initialization extends Archetype {
    preprocess() {
        // ...

        life.consecutive.perfect.set({
            increment: 50,
            step: 10,
        })

        // ...
    }

    // ...
}
export class Initialization extends Archetype {
    preprocess() {
        // ...

        life.consecutive.perfect.set({
            increment: 50,
            step: 10,
        })

        // ...
    }

    // ...
}

Secondary Metric UI

Similar to primary metric UI, there are also secondary metric bar and secondary metric value UI, which is often used to display life.

export class Initialization extends Archetype {
    preprocess() {
        // ...

        ui.metric.secondary.bar.set({
            anchor: screen.rect.rt
                .sub(new Vec(0.05, 0.05))
                .sub(new Vec(0, 0.15).mul(ui.configuration.metric.primary.scale))
                .sub(new Vec(0, 0.05)),
            pivot: { x: 1, y: 1 },
            size: new Vec(0.75, 0.15).mul(ui.configuration.metric.secondary.scale),
            rotation: 0,
            alpha: ui.configuration.metric.secondary.alpha,
            horizontalAlign: HorizontalAlign.Left,
            background: true,
        })
        ui.metric.secondary.value.set({
            anchor: screen.rect.rt
                .sub(new Vec(0.05, 0.05))
                .sub(new Vec(0, 0.15).mul(ui.configuration.metric.primary.scale))
                .sub(new Vec(0, 0.05))
                .sub(new Vec(0.035, 0.035).mul(ui.configuration.metric.secondary.scale)),
            pivot: { x: 1, y: 1 },
            size: new Vec(0, 0.08).mul(ui.configuration.metric.secondary.scale),
            rotation: 0,
            alpha: ui.configuration.metric.secondary.alpha,
            horizontalAlign: HorizontalAlign.Right,
            background: false,
        })

        // ...
    }

    // ...
}
export class Initialization extends Archetype {
    preprocess() {
        // ...

        ui.metric.secondary.bar.set({
            anchor: screen.rect.rt
                .sub(new Vec(0.05, 0.05))
                .sub(new Vec(0, 0.15).mul(ui.configuration.metric.primary.scale))
                .sub(new Vec(0, 0.05)),
            pivot: { x: 1, y: 1 },
            size: new Vec(0.75, 0.15).mul(ui.configuration.metric.secondary.scale),
            rotation: 0,
            alpha: ui.configuration.metric.secondary.alpha,
            horizontalAlign: HorizontalAlign.Left,
            background: true,
        })
        ui.metric.secondary.value.set({
            anchor: screen.rect.rt
                .sub(new Vec(0.05, 0.05))
                .sub(new Vec(0, 0.15).mul(ui.configuration.metric.primary.scale))
                .sub(new Vec(0, 0.05))
                .sub(new Vec(0.035, 0.035).mul(ui.configuration.metric.secondary.scale)),
            pivot: { x: 1, y: 1 },
            size: new Vec(0, 0.08).mul(ui.configuration.metric.secondary.scale),
            rotation: 0,
            alpha: ui.configuration.metric.secondary.alpha,
            horizontalAlign: HorizontalAlign.Right,
            background: false,
        })

        // ...
    }

    // ...
}