States & SubStates
Games in Flixel-Pixi are organized into scenes called States (FlxState). Modal menus, pause screens, and inventories are handled through layered SubStates (FlxSubState).
The FlxState Lifecycle
┌───────────────┐
│ Constructor │
└───────┬───────┘
│
▼
┌───────────────┐
│ create() │ ◄── Initialize objects, groups, cameras
└───────┬───────┘
│
┌─────────────▼─────────────┐
│ │
▼ ▼
┌───────────────┐ ┌───────────────┐
│update(elapsed)│ │ draw() │
└───────┬───────┘ └───────────────┘
│
▼ (On switch state)
┌───────────────┐
│ destroy() │ ◄── Releases textures, groups, listeners
└───────────────┘Creating a State
ts
import { FlxButton, FlxSprite, FlxState, FlxText } from 'flixel-pixi';
import { PlayState } from './PlayState';
export class MenuState extends FlxState {
override create(): void {
super.create();
const title = new FlxText(0, 140, 640, 'MY RETRO ADVENTURE', 28);
title.alignment = 'center';
this.add(title);
const startBtn = new FlxButton(260, 260, 'START GAME', () => {
this.switchState(new PlayState());
});
this.add(startBtn);
}
}Switching States
To transition to a new state:
ts
this.switchState(new NextState());When switching states:
- The incoming state is instantiated and its
create()method is invoked. - The previous state's
destroy()is called automatically, tearing down all children and cleaning up GPU render handles.
Modal Pause Screens with FlxSubState
A FlxSubState runs on top of the current state. When active, it can optionally pause the parent state's simulation (update) while still drawing it in the background.
ts
import { FlxButton, FlxSubState, FlxText } from 'flixel-pixi';
export class PauseSubState extends FlxSubState {
override create(): void {
super.create();
// Dark semi-transparent background overlay
this.bgColor = 0x88000000;
const pauseLabel = new FlxText(0, 180, 640, 'PAUSED', 24);
pauseLabel.alignment = 'center';
this.add(pauseLabel);
const resumeBtn = new FlxButton(260, 260, 'RESUME', () => {
this.close(); // Close substate and resume gameplay
});
this.add(resumeBtn);
}
}Opening & Closing a SubState
From your PlayState:
ts
// Open pause substate
if (this.context.input.keyboard.justPressed('ESCAPE')) {
this.openSubState(new PauseSubState());
}Best Practices
- Always allocate game objects inside
create(), not the constructor, so the runtime context (this.context) is fully bound. - Call
super.create(),super.update(elapsed), andsuper.destroy()to ensure internal group processing and cleanup occur properly.