Claude
Skills
Sign in
Back

events-system

Included with Lifetime
$97 forever

Use this skill when working with the Phaser 4 event system. Covers EventEmitter, scene events, game events, custom events, and event-driven communication. Triggers on: events, on, emit, EventEmitter, scene events, listeners.

General

What this skill does


# Events System

> Phaser uses the EventEmitter pattern (via eventemitter3) throughout the entire framework. Every major system -- Game, Scene, Input, Loader, Cameras, Sound, Tweens, Physics, Textures, Animations -- is an EventEmitter or contains one. Events use lowercase string keys. Phaser provides named constants for all built-in events to avoid typos and enable IDE autocomplete.

**Key source paths:** `src/events/EventEmitter.js`, `src/scene/events/`, `src/core/events/`, `src/input/events/`, `src/loader/events/`, `src/animations/events/`, `src/cameras/2d/events/`, `src/sound/events/`, `src/tweens/events/`, `src/physics/arcade/events/`, `src/textures/events/`, `src/gameobjects/events/`, `src/time/events/`
**Related skills:** ../scenes/SKILL.md, ../input-keyboard-mouse-touch/SKILL.md

## Quick Start

```js
// on — listen for an event (persists until removed)
this.input.on('pointerdown', (pointer) => {
    console.log('clicked at', pointer.x, pointer.y);
});

// once — listen for an event, auto-removes after first fire
this.events.once('shutdown', () => {
    console.log('scene shutting down');
});

// off — remove a specific listener (must pass same function reference)
const handler = (pointer) => { /* ... */ };
this.input.on('pointerdown', handler);
this.input.off('pointerdown', handler);

// emit — fire a custom event with arguments
this.events.emit('player-died', this.player, this.score);

// removeAllListeners — remove all listeners for an event (or all events)
this.events.removeAllListeners('player-died');
this.events.removeAllListeners(); // all events
```

### Using Named Constants (Preferred)

```js
// Always prefer constants over raw strings to prevent typos
this.events.on(Phaser.Scenes.Events.UPDATE, (time, delta) => {
    // runs every frame
});

this.input.on(Phaser.Input.Events.POINTER_DOWN, (pointer) => {
    // pointer pressed
});

this.game.events.on(Phaser.Core.Events.BLUR, () => {
    // browser tab lost focus
});
```

## Core Concepts

### EventEmitter Base Class

`Phaser.Events.EventEmitter` extends eventemitter3. It adds `shutdown()` and `destroy()` methods that both call `removeAllListeners()`.

**Full API (inherited from eventemitter3):**

| Method | Description |
|---|---|
| `on(event, fn, context?)` | Add persistent listener. Returns `this` for chaining |
| `addListener(event, fn, context?)` | Alias for `on` |
| `once(event, fn, context?)` | Add one-time listener; auto-removed after first fire |
| `off(event, fn?, context?, once?)` | Remove listener(s). Must pass same `fn` reference to remove specific listener |
| `removeListener(event, fn?, context?, once?)` | Alias for `off` |
| `removeAllListeners(event?)` | Remove all listeners for event, or all events if no arg |
| `emit(event, ...args)` | Fire event. Returns `true` if it had listeners |
| `listeners(event)` | Return array of listener functions for an event |
| `listenerCount(event)` | Return number of listeners for an event |
| `eventNames()` | Return array of event names that have listeners |
| `shutdown()` | Calls `removeAllListeners()` |
| `destroy()` | Calls `removeAllListeners()` |

### Event Strings vs Constants

Every built-in event is a lowercase string exported as a constant. The constant name maps predictably to the string:

```js
Phaser.Scenes.Events.UPDATE        // 'update'
Phaser.Scenes.Events.PRE_UPDATE    // 'preupdate'
Phaser.Scenes.Events.SHUTDOWN      // 'shutdown'
Phaser.Core.Events.BOOT            // 'boot'
Phaser.Input.Events.POINTER_DOWN   // 'pointerdown'
```

Some events use a key-suffix pattern for per-key listening:

```js
// Loader: listen for a specific file completing
this.load.on(Phaser.Loader.Events.FILE_KEY_COMPLETE + 'image-logo', (key, type, data) => {});
// String value: 'filecomplete-image-logo'

// Animations: listen for a specific animation completing on a sprite
sprite.on(Phaser.Animations.Events.ANIMATION_COMPLETE_KEY + 'walk', () => {});
// String value: 'animationcomplete-walk'

// Textures: listen for a specific texture being added
this.textures.on(Phaser.Textures.Events.ADD_KEY + 'myTexture', () => {});
// String value: 'addtexture-myTexture'
```

### Context (Third Argument)

The third argument to `on`/`once` sets `this` inside the callback. Defaults to the emitter.

```js
// 'this' inside handler refers to the scene
this.input.on('pointerdown', function (pointer) {
    this.cameras.main.shake(100); // 'this' = scene
}, this);

// Arrow functions ignore the context argument (they capture lexical 'this')
this.input.on('pointerdown', (pointer) => {
    this.cameras.main.shake(100); // 'this' = enclosing scope (scene in create)
});
```

## Common Patterns

### Scene Lifecycle Events

Frame loop order: `preupdate` -> `update` -> `Scene.update()` -> `postupdate` -> `prerender` -> `render`

```js
create() {
    this.events.on(Phaser.Scenes.Events.UPDATE, this.onUpdate, this);
    // CRITICAL: always clean up on shutdown to prevent leaks on scene restart
    this.events.on(Phaser.Scenes.Events.SHUTDOWN, () => {
        this.events.off(Phaser.Scenes.Events.UPDATE, this.onUpdate, this);
        this.input.off('pointerdown', this.onPointerDown, this);
    });
}
```

### Game-Level Events

```js
// game.events fires on the Game instance, shared across all scenes
// Access from a scene via this.game.events
this.game.events.on(Phaser.Core.Events.BLUR, this.handleBlur, this);
this.game.events.on(Phaser.Core.Events.VISIBLE, this.handleVisible, this);
```

### Inter-Scene Communication

```js
// METHOD 1: game.events — a global event bus accessible from all scenes
// Scene A emits:
this.game.events.emit('score-changed', this.score);
// Scene B listens:
this.game.events.on('score-changed', (score) => { this.scoreText.setText(score); });

// METHOD 2: this.registry — a shared DataManager across all scenes
// The registry is a Phaser.Data.DataManager on the Game instance.
// Scene A sets data:
this.registry.set('score', 100);
// Scene B listens for changes:
this.registry.events.on('changedata-score', (parent, value, previousValue) => {
    this.scoreText.setText(value);
});

// METHOD 3: Direct scene access via ScenePlugin
this.scene.get('UIScene').events.emit('update-health', hp);
```

### Custom Events

```js
// Emit custom events with arbitrary data arguments
this.events.emit('player-died', this.player, { lives: this.lives });
this.events.on('player-died', (player, data) => {
    console.log('Lives remaining:', data.lives);
});
```

## All Event Namespaces Reference

### Scene Events (`Phaser.Scenes.Events`)

Emitter: `this.events` (the Scene's Systems EventEmitter)

| Constant | String | When |
|---|---|---|
| `BOOT` | `'boot'` | Scene Systems boot (for plugins) |
| `READY` | `'ready'` | Scene Systems fully ready |
| `START` | `'start'` | Scene starts running |
| `CREATE` | `'create'` | After Scene.create() completes |
| `PRE_UPDATE` | `'preupdate'` | Before update each frame |
| `UPDATE` | `'update'` | Main update each frame |
| `POST_UPDATE` | `'postupdate'` | After update each frame |
| `PRE_RENDER` | `'prerender'` | Before render each frame |
| `RENDER` | `'render'` | During render each frame |
| `PAUSE` | `'pause'` | Scene paused |
| `RESUME` | `'resume'` | Scene resumed from pause |
| `SLEEP` | `'sleep'` | Scene put to sleep |
| `WAKE` | `'wake'` | Scene woken from sleep |
| `SHUTDOWN` | `'shutdown'` | Scene shutting down (may restart) |
| `DESTROY` | `'destroy'` | Scene permanently destroyed |
| `ADDED_TO_SCENE` | `'addedtoscene'` | GameObject added to scene |
| `REMOVED_FROM_SCENE` | `'removedfromscene'` | GameObject removed from scene |
| `TRANSITION_INIT` | `'transitioninit'` | Transition initialized (target scene) |
| `TRANSITION_START` | `'transitionstart'` | Transition started (target scene) |
| `TRANSITION_OUT` | `'transitionout'` | Transition out (source scene) |
| `TRANSITION_COMPLETE` | `'transitioncomplete'` | Transition finished |
| `TRANSITION_WAKE` | `'transitionwake'` | Transition wakes target scene |

### Game E
Files: 1
Size: 21.6 KB
Complexity: 26/100
Category: General

Related in General