Skip to content

03 Screen

In this chapter, we will set up the screen.

Engine Coordinate System

As in play mode, the tutorial uses the engine coordinate system for sprites and particles. The shared init_layout function uses the boundaries from screen, then builds the transform with Transform2d and applies it to sprites and particles:

python
from sonolus.script.runtime import screen, set_particle_transform, set_skin_transform
from sonolus.script.transform import Transform2d
from sonolus.script.vec import Vec2


def init_layout(note_size: float):
    note_radius = 0.2 * note_size
    judge_line_y = -0.6

    t = screen().t + note_radius
    b = judge_line_y
    h = t - b

    transform = Transform2d.new().scale(Vec2(h, -h)).translate(Vec2(0, t))

    set_skin_transform(transform)
    set_particle_transform(transform)

    # ...

This code is for reference. Do not change init_layout. The tutorial reuses it from play mode. The negative vertical scale makes increasing y move downward: y = 0 is the note's starting position, and y = 1 is the judgment line.

Replace guide/tutorial/preprocess.py with the following code. init_layout(1) uses the base note size instead of the gameplay option. The template provides reset_phase() in guide/tutorial/navigate.py. Call it to start the phase clock at zero:

python
from guide.lib.layout import init_layout
from guide.lib.ui import init_ui
from guide.tutorial.navigate import reset_phase


def preprocess():
    init_ui()
    init_layout(1)
    reset_phase()

Shared Data

The stage and note drawing functions need the values calculated during preprocessing. The shared Config class stores them as level_data. This declaration is for reference. Do not add it again:

python
from sonolus.script.globals import level_data


@level_data
class Config:
    judge_line_l: float
    judge_line_r: float
    note_radius: float

The @level_data decorator uses the Tutorial Data block when the engine is compiled for tutorial mode. The values are writable during preprocess and readable during the tutorial's other callbacks.

The existing init_layout function calculates and stores the shared values as follows. This code is also for reference:

python
def init_layout(note_size: float):
    # ...

    Config.judge_line_l = screen().l / h
    Config.judge_line_r = screen().r / h
    Config.note_radius = note_radius / h

This setup has no new visible result until the stage is drawn in the next chapter.