Skip to content

Scene changes

Transitions, scenes over scenes, loading screens and menu actions.

Files: scene_flow.odin.

From scene_flow.odin:

Moving between scenes: transitions (a fade or a wipe over the switch), scenes over scenes (a pause menu or an inventory opened over the level, which waits under it) and a loading screen (a scene shown while the next one’s images and sounds load).

  • Transitions (Transition, Game_ChangeScene): the screen is covered (Fade to a color, a Wipe from a side, a closing Circle) over the first half of duration, the scene changes under the cover, and it’s uncovered over the second half. The project’s transition (project.xml’s transition, transitionTime, transitionColor; Game.flow.transition) is used by Menu and Button actions scene:<Name> and by Game_ChangeScene without one.
  • Scenes over scenes (Game_PushScene, Game_PopScene; actions push:<Name> and pop): the pushed scene is drawn over the others and updated; with pauseBelow (the default) the scenes under it don’t update (they still draw), so a pause menu freezes the level. A change of scene closes them all.
  • The loading screen (project.xml’s loadingScene; Game.flow.loadingScene): with one, the game builds only its start scene and the loading scene when it starts; any other scene is built when it’s entered, after the loading scene has been shown while its images and sounds load (a few a frame: LOADING_PER_FRAME, at least LOADING_MIN_SECONDS on screen). Game_LoadingProgress (0 to 1) feeds its progress bar (a ProgressBar whose showLoading is set does it by itself).
TransitionKind :: enum {
// None: the scene changes at once
None,
// The screen fades to `color` and back
Fade,
// `color` sweeps across from a side
Wipe_Left,
Wipe_Right,
Wipe_Up,
Wipe_Down,
// A circle of `color` closes on the middle, then opens
Circle,
}

What covers the screen between two scenes

enum. Source: scene_flow.odin:31

Transition :: struct {
kind: TransitionKind,
// Seconds, covering and uncovering together
duration: f32,
// The cover's color
color: sdl.Color,
}

How a scene change looks (Game_ChangeScene)

struct. Source: scene_flow.odin:46

FlowPhase :: enum {
Idle,
// Covering the old scene
Covering,
// Uncovering the loading scene
Showing_Loading,
// Loading the target's images and sounds under the loading scene
Loading,
// Covering the loading scene
Leaving_Loading,
// Uncovering the new scene
Uncovering,
}

Where a scene change is (SceneFlow.phase)

enum. Source: scene_flow.odin:64

SceneOverlay :: struct {
scene: ^Scene,
// The scenes under it don't update while it's there
pauseBelow: bool,
}

A scene over the game’s scene (Game_PushScene)

struct. Source: scene_flow.odin:79

SceneFlow :: struct {
// The project's transition (used when a change names none)
transition: Transition,
// The project's loading scene ("": none)
loadingScene: string,
// The change under way
phase: FlowPhase,
active: Transition,
time: f32,
// The scene being changed to (game arena)
target: string,
// Its images and sounds still to load, how many there were, and seconds the loading scene showed
toLoad: [dynamic]string,
loadTotal: int,
loadingTime: f32,
// Scenes over the game's scene, bottom first
overlays: [dynamic]SceneOverlay,
}

A game’s scene changes, overlays and loading (Game.flow)

struct. Source: scene_flow.odin:86

Game_ChangeScene :: proc(game: ^Game, name: string, transition: Maybe(Transition) = nil) -> bool

Changes scene with a transition: the screen is covered, the scene changes, it’s uncovered (and with a loading scene, that one shows while the new scene loads).

Inputs

  • game: The game
  • name: The scene
  • transition: How (nil: the project’s; {kind = .None}: at once)

Returns

  • false when there’s no such scene

Example

e.Game_ChangeScene(game, "Level2", e.Transition{kind = .Fade, duration = 0.6, color = {0, 0, 0, 255}})

procedure. Source: scene_flow.odin:120

Game_PushScene :: proc(game: ^Game, name: string, pauseBelow := true) -> bool

Opens a scene over the playing one (a pause menu, an inventory): drawn over it and updated; with pauseBelow the scenes under it wait (they still draw).

Inputs

  • game: The game
  • name: The scene
  • pauseBelow: The scenes under it don’t update while it’s open

Returns

  • false when there’s no such scene

Example

e.Game_PushScene(game, "PauseMenu")

procedure. Source: scene_flow.odin:163

Game_PopScene :: proc(game: ^Game) -> bool

Closes the scene on top (the last Game_PushScene’s).

Inputs

  • game: The game

Returns

  • false when no scene is open over the game’s

procedure. Source: scene_flow.odin:185

Game_TopScene :: proc(game: ^Game) -> ^Scene

The scene on top: the last one pushed, else the game’s.

procedure. Source: scene_flow.odin:196

Game_LoadingProgress :: proc(game: ^Game) -> f32

How far the loading screen has got: 0 to 1 (1 when nothing is loading).

procedure. Source: scene_flow.odin:204

Game_IsChangingScene :: proc(game: ^Game) -> bool

Whether a scene change or an uncovering is under way.

procedure. Source: scene_flow.odin:213

Game_RunAction :: proc(game: ^Game, action: string) -> bool

Runs a scene action string (Menu items’, Buttons’): “scene:<Name>” (with the project’s transition), “push:<Name>”, “pop”, “quit”.

Inputs

  • game: The game
  • action: The action

Returns

  • false when it isn’t one of these (logged by the caller)

procedure. Source: scene_flow.odin:228

DEFAULT_TRANSITION :: Transition{kind = .None, duration = 0.5, color = {0, 0, 0, 255}}

The transition when the project sets none: a black fade of half a second, off

constant. Source: scene_flow.odin:55

LOADING_PER_FRAME :: 4

Images and sounds a loading screen loads each frame

constant. Source: scene_flow.odin:58

LOADING_MIN_SECONDS :: 0.4

The least time a loading screen shows (it doesn’t flash by)

constant. Source: scene_flow.odin:61