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
```