or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

actions.mdanimation.mdaudio.mdcameras.mddata-management.mdevents.mdgame-objects.mdindex.mdinput.mdloading.mdmath-geometry.mdphysics.mdrendering.mdscenes.mdtweens.mdutilities.md

events.mddocs/

0

# Events System

1

2

Phaser's event system is built on EventEmitter3, providing powerful event-driven programming capabilities throughout the framework. Events enable decoupled communication between game objects, scenes, and systems.

3

4

## Capabilities

5

6

### Core Event Methods

7

8

All Phaser objects that emit events (Scene, GameObject, etc.) provide these core event methods:

9

10

```javascript { .api }

11

// Add event listener

12

scene.events.on('eventName', function(data) {

13

console.log('Event received:', data);

14

});

15

16

// Add one-time event listener

17

scene.events.once('eventName', function(data) {

18

console.log('This will only fire once:', data);

19

});

20

21

// Remove event listener

22

scene.events.off('eventName', callbackFunction);

23

24

// Remove all listeners for an event

25

scene.events.off('eventName');

26

27

// Remove all listeners for all events

28

scene.events.removeAllListeners();

29

30

// Emit event

31

scene.events.emit('eventName', data);

32

33

// Check if event has listeners

34

const hasListeners = scene.events.listenerCount('eventName') > 0;

35

36

// Get all event names

37

const eventNames = scene.events.eventNames();

38

```

39

40

### Scene Events

41

42

Scene lifecycle and management events:

43

44

```javascript { .api }

45

// Scene lifecycle events

46

scene.events.on('preupdate', function(time, delta) {

47

// Called before scene update

48

});

49

50

scene.events.on('update', function(time, delta) {

51

// Called during scene update

52

});

53

54

scene.events.on('postupdate', function(time, delta) {

55

// Called after scene update

56

});

57

58

scene.events.on('render', function(renderer) {

59

// Called during rendering

60

});

61

62

scene.events.on('pause', function() {

63

// Scene was paused

64

});

65

66

scene.events.on('resume', function() {

67

// Scene was resumed

68

});

69

70

scene.events.on('sleep', function() {

71

// Scene went to sleep

72

});

73

74

scene.events.on('wake', function() {

75

// Scene woke up

76

});

77

78

scene.events.on('shutdown', function() {

79

// Scene is shutting down

80

});

81

82

scene.events.on('destroy', function() {

83

// Scene is being destroyed

84

});

85

86

// Scene transition events

87

scene.events.on('transitionstart', function(fromScene, duration) {

88

console.log(`Transitioning from ${fromScene.scene.key} over ${duration}ms`);

89

});

90

91

scene.events.on('transitioncomplete', function(fromScene) {

92

console.log(`Transition completed from ${fromScene.scene.key}`);

93

});

94

```

95

96

### GameObject Events

97

98

Game objects emit various events for interaction and lifecycle management:

99

100

```javascript { .api }

101

// Make GameObject interactive and listen for input events

102

sprite.setInteractive();

103

104

sprite.on('pointerdown', function(pointer, localX, localY, event) {

105

console.log('Sprite clicked at:', localX, localY);

106

});

107

108

sprite.on('pointerup', function(pointer, localX, localY, event) {

109

console.log('Sprite released');

110

});

111

112

sprite.on('pointermove', function(pointer, localX, localY, event) {

113

console.log('Pointer moved over sprite');

114

});

115

116

sprite.on('pointerover', function(pointer, localX, localY, event) {

117

console.log('Pointer entered sprite');

118

sprite.setTint(0xffff00); // Yellow tint on hover

119

});

120

121

sprite.on('pointerout', function(pointer, event) {

122

console.log('Pointer left sprite');

123

sprite.clearTint(); // Remove tint

124

});

125

126

// Drag events

127

sprite.on('dragstart', function(pointer, dragX, dragY) {

128

console.log('Started dragging sprite');

129

});

130

131

sprite.on('drag', function(pointer, dragX, dragY) {

132

sprite.x = dragX;

133

sprite.y = dragY;

134

});

135

136

sprite.on('dragend', function(pointer, dragX, dragY, dropped) {

137

console.log('Stopped dragging sprite');

138

});

139

140

// GameObject lifecycle events

141

sprite.on('destroy', function() {

142

console.log('Sprite is being destroyed');

143

});

144

```

145

146

### Input Events

147

148

Global input events available through the scene's input manager:

149

150

```javascript { .api }

151

// Global pointer events

152

scene.input.on('pointerdown', function(pointer) {

153

console.log('Pointer down at:', pointer.x, pointer.y);

154

});

155

156

scene.input.on('pointerup', function(pointer) {

157

console.log('Pointer up at:', pointer.x, pointer.y);

158

});

159

160

scene.input.on('pointermove', function(pointer) {

161

console.log('Pointer moved to:', pointer.x, pointer.y);

162

});

163

164

// Keyboard events

165

scene.input.keyboard.on('keydown', function(event) {

166

console.log('Key pressed:', event.code);

167

});

168

169

scene.input.keyboard.on('keyup', function(event) {

170

console.log('Key released:', event.code);

171

});

172

173

// Specific key events

174

const spaceKey = scene.input.keyboard.addKey('SPACE');

175

spaceKey.on('down', function() {

176

console.log('Space key pressed');

177

});

178

179

spaceKey.on('up', function() {

180

console.log('Space key released');

181

});

182

183

// Gamepad events

184

scene.input.gamepad.on('connected', function(pad) {

185

console.log('Gamepad connected:', pad.id);

186

});

187

188

scene.input.gamepad.on('disconnected', function(pad) {

189

console.log('Gamepad disconnected:', pad.id);

190

});

191

```

192

193

### Animation Events

194

195

Animation and tween events for coordinating visual effects:

196

197

```javascript { .api }

198

// Sprite animation events

199

sprite.on('animationstart', function(animation, frame) {

200

console.log('Animation started:', animation.key);

201

});

202

203

sprite.on('animationupdate', function(animation, frame) {

204

console.log('Animation frame changed:', frame.index);

205

});

206

207

sprite.on('animationcomplete', function(animation, frame) {

208

console.log('Animation completed:', animation.key);

209

});

210

211

sprite.on('animationrepeat', function(animation, frame) {

212

console.log('Animation repeated:', animation.key);

213

});

214

215

// Tween events

216

const tween = scene.tweens.add({

217

targets: sprite,

218

x: 400,

219

duration: 2000,

220

onStart: function() {

221

console.log('Tween started');

222

},

223

onUpdate: function() {

224

console.log('Tween updated');

225

},

226

onComplete: function() {

227

console.log('Tween completed');

228

}

229

});

230

231

// Listen to tween events externally

232

tween.on('start', function() {

233

console.log('Tween started (external listener)');

234

});

235

236

tween.on('complete', function() {

237

console.log('Tween completed (external listener)');

238

});

239

```

240

241

### Physics Events

242

243

Physics system events for collision detection and interaction:

244

245

```javascript { .api }

246

// Arcade Physics collision events

247

const player = scene.physics.add.sprite(100, 100, 'player');

248

const enemy = scene.physics.add.sprite(200, 100, 'enemy');

249

250

// Collision detection with callback

251

scene.physics.add.collider(player, enemy, function(player, enemy) {

252

console.log('Player collided with enemy');

253

player.setTint(0xff0000); // Red tint on collision

254

});

255

256

// Overlap detection (no physics separation)

257

scene.physics.add.overlap(player, enemy, function(player, enemy) {

258

console.log('Player overlapped with enemy');

259

});

260

261

// Matter.js physics events

262

scene.matter.world.on('collisionstart', function(event) {

263

const pairs = event.pairs;

264

pairs.forEach(function(pair) {

265

const bodyA = pair.bodyA;

266

const bodyB = pair.bodyB;

267

console.log('Collision started between:', bodyA.label, bodyB.label);

268

});

269

});

270

271

scene.matter.world.on('collisionend', function(event) {

272

console.log('Collision ended');

273

});

274

```

275

276

### Audio Events

277

278

Audio system events for sound management:

279

280

```javascript { .api }

281

// Sound events

282

const music = scene.sound.add('backgroundMusic');

283

284

music.on('play', function() {

285

console.log('Music started playing');

286

});

287

288

music.on('pause', function() {

289

console.log('Music paused');

290

});

291

292

music.on('resume', function() {

293

console.log('Music resumed');

294

});

295

296

music.on('stop', function() {

297

console.log('Music stopped');

298

});

299

300

music.on('complete', function() {

301

console.log('Music finished playing');

302

});

303

304

music.on('looped', function() {

305

console.log('Music looped');

306

});

307

308

// Global sound manager events

309

scene.sound.on('mute', function() {

310

console.log('All sounds muted');

311

});

312

313

scene.sound.on('unmute', function() {

314

console.log('All sounds unmuted');

315

});

316

317

scene.sound.on('volume', function(volume) {

318

console.log('Master volume changed to:', volume);

319

});

320

```

321

322

### Custom Events

323

324

Create and manage custom events for game-specific communication:

325

326

```javascript { .api }

327

// Create custom event system

328

class GameEventManager extends Phaser.Events.EventEmitter {

329

constructor() {

330

super();

331

}

332

333

playerScored(points) {

334

this.emit('player-scored', points);

335

}

336

337

enemyDefeated(enemyType, points) {

338

this.emit('enemy-defeated', enemyType, points);

339

}

340

341

levelCompleted(levelNumber, time) {

342

this.emit('level-completed', levelNumber, time);

343

}

344

}

345

346

// Use custom events

347

const gameEvents = new GameEventManager();

348

349

// Listen for custom events

350

gameEvents.on('player-scored', function(points) {

351

console.log('Player scored:', points);

352

updateScoreDisplay(points);

353

});

354

355

gameEvents.on('enemy-defeated', function(enemyType, points) {

356

console.log(`Defeated ${enemyType} for ${points} points`);

357

addFloatingText(`+${points}`, enemy.x, enemy.y);

358

});

359

360

gameEvents.on('level-completed', function(levelNumber, time) {

361

console.log(`Level ${levelNumber} completed in ${time}ms`);

362

showCompletionBonus(levelNumber, time);

363

});

364

365

// Emit custom events

366

gameEvents.playerScored(100);

367

gameEvents.enemyDefeated('goblin', 50);

368

gameEvents.levelCompleted(1, 45000);

369

```

370

371

### Event Management Patterns

372

373

```javascript { .api }

374

// Event cleanup on scene shutdown

375

scene.events.on('shutdown', function() {

376

// Clean up global event listeners

377

gameEvents.removeAllListeners();

378

379

// Clean up input listeners

380

scene.input.keyboard.removeAllListeners();

381

382

// Clean up physics events

383

scene.physics.world.removeAllListeners();

384

});

385

386

// Conditional event handling

387

let gameState = 'playing';

388

389

scene.input.on('pointerdown', function(pointer) {

390

if (gameState === 'playing') {

391

handleGameplayClick(pointer);

392

} else if (gameState === 'paused') {

393

handlePausedClick(pointer);

394

}

395

});

396

397

// Event delegation pattern

398

scene.events.on('custom-action', function(actionType, data) {

399

switch(actionType) {

400

case 'heal-player':

401

player.heal(data.amount);

402

break;

403

case 'damage-enemy':

404

data.enemy.takeDamage(data.amount);

405

break;

406

case 'collect-item':

407

inventory.addItem(data.item);

408

break;

409

}

410

});

411

412

// Event with context binding

413

class Player {

414

constructor(scene, x, y) {

415

this.scene = scene;

416

this.sprite = scene.add.sprite(x, y, 'player');

417

this.health = 100;

418

419

// Bind event handlers to maintain context

420

scene.events.on('enemy-attack', this.takeDamage, this);

421

scene.events.on('heal-pickup', this.heal, this);

422

}

423

424

takeDamage(amount) {

425

this.health -= amount;

426

if (this.health <= 0) {

427

this.die();

428

}

429

}

430

431

heal(amount) {

432

this.health = Math.min(100, this.health + amount);

433

}

434

435

die() {

436

this.scene.events.emit('player-died');

437

this.sprite.destroy();

438

}

439

}

440

```

441

442

## Types

443

444

```javascript { .api }

445

class EventEmitter {

446

// Event registration

447

on(event: string, fn: function, context?: any): this;

448

once(event: string, fn: function, context?: any): this;

449

off(event?: string, fn?: function, context?: any): this;

450

451

// Event emission

452

emit(event: string, ...args: any[]): boolean;

453

454

// Event introspection

455

eventNames(): string[];

456

listenerCount(event: string): number;

457

listeners(event: string): function[];

458

459

// Cleanup

460

removeAllListeners(event?: string): this;

461

destroy(): void;

462

}

463

464

// Common event callback signatures

465

type PointerEventCallback = (pointer: Phaser.Input.Pointer, localX?: number, localY?: number, event?: Phaser.Types.Input.EventData) => void;

466

type KeyboardEventCallback = (event: KeyboardEvent) => void;

467

type AnimationEventCallback = (animation: Phaser.Animations.Animation, frame: Phaser.Animations.AnimationFrame) => void;

468

type TweenEventCallback = (tween: Phaser.Tweens.Tween, targets: any[]) => void;

469

type SceneEventCallback = (time?: number, delta?: number) => void;

470

```