events-system

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

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
Phaser 在整个框架中采用了EventEmitter模式(基于eventemitter3实现)。所有主要系统——Game、Scene、Input、Loader、Cameras、Sound、Tweens、Physics、Textures、Animations——要么本身就是EventEmitter,要么内部包含EventEmitter。事件使用小写字符串作为键。Phaser为所有内置事件提供了命名常量,以避免拼写错误并支持IDE自动补全。
核心源码路径:
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/
相关技能: ../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
js
// on — 监听事件(持续生效直到被移除)
this.input.on('pointerdown', (pointer) => {
    console.log('点击位置:', pointer.x, pointer.y);
});

// once — 监听事件,触发一次后自动移除
this.events.once('shutdown', () => {
    console.log('场景正在关闭');
});

// off — 移除特定监听器(必须传入相同的函数引用)
const handler = (pointer) => { /* ... */ };
this.input.on('pointerdown', handler);
this.input.off('pointerdown', handler);

// emit — 触发自定义事件并传递参数
this.events.emit('player-died', this.player, this.score);

// removeAllListeners — 移除某个事件的所有监听器(或所有事件的监听器)
this.events.removeAllListeners('player-died');
this.events.removeAllListeners(); // 移除所有事件的监听器

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
});
js
// 始终优先使用常量而非原始字符串,以避免拼写错误
this.events.on(Phaser.Scenes.Events.UPDATE, (time, delta) => {
    // 每帧执行
});

this.input.on(Phaser.Input.Events.POINTER_DOWN, (pointer) => {
    // 指针按下
});

this.game.events.on(Phaser.Core.Events.BLUR, () => {
    // 浏览器标签失去焦点
});

Core Concepts

核心概念

EventEmitter Base Class

EventEmitter基类

Phaser.Events.EventEmitter
extends eventemitter3. It adds
shutdown()
and
destroy()
methods that both call
removeAllListeners()
.
Full API (inherited from eventemitter3):
MethodDescription
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()
Phaser.Events.EventEmitter
继承自eventemitter3,新增了
shutdown()
destroy()
方法,两者都会调用
removeAllListeners()
完整API(继承自eventemitter3):
方法描述
on(event, fn, context?)
添加持久化监听器,返回
this
以支持链式调用
addListener(event, fn, context?)
on
的别名
once(event, fn, context?)
添加一次性监听器,触发一次后自动移除
off(event, fn?, context?, once?)
移除监听器。移除特定监听器时必须传入相同的
fn
引用
removeListener(event, fn?, context?, once?)
off
的别名
removeAllListeners(event?)
移除某个事件的所有监听器,若未传参数则移除所有事件的监听器
emit(event, ...args)
触发事件,若存在监听器则返回
true
listeners(event)
返回某个事件的监听器函数数组
listenerCount(event)
返回某个事件的监听器数量
eventNames()
返回存在监听器的事件名称数组
shutdown()
调用
removeAllListeners()
destroy()
调用
removeAllListeners()

Event Strings vs Constants

事件字符串 vs 常量

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'
每个内置事件都是一个小写字符串,并以常量形式导出。常量名称与字符串的映射规则清晰可预测:
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'
部分事件采用“键-后缀”模式,支持针对特定键的监听:
js
// Loader:监听特定文件加载完成
this.load.on(Phaser.Loader.Events.FILE_KEY_COMPLETE + 'image-logo', (key, type, data) => {});
// 字符串值:'filecomplete-image-logo'

// Animations:监听精灵上特定动画完成
sprite.on(Phaser.Animations.Events.ANIMATION_COMPLETE_KEY + 'walk', () => {});
// 字符串值:'animationcomplete-walk'

// Textures:监听特定纹理添加完成
this.textures.on(Phaser.Textures.Events.ADD_KEY + 'myTexture', () => {});
// 字符串值:'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)
});
on
/
once
的第三个参数用于设置回调函数内部的
this
指向,默认指向事件发射器。
js
// 回调内部的'this'指向场景
this.input.on('pointerdown', function (pointer) {
    this.cameras.main.shake(100); // 'this' = 场景
}, this);

// 箭头函数会忽略上下文参数(它们捕获词法作用域的'this')
this.input.on('pointerdown', (pointer) => {
    this.cameras.main.shake(100); // 'this' = 封闭作用域(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);
    });
}
帧循环顺序:
preupdate
->
update
->
Scene.update()
->
postupdate
->
prerender
->
render
js
create() {
    this.events.on(Phaser.Scenes.Events.UPDATE, this.onUpdate, this);
    // 重要提示:务必在shutdown时清理监听器,避免场景重启时出现内存泄漏
    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);
js
// game.events 在Game实例上触发,所有场景共享
// 在场景中可通过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);
js
// 方法1:game.events — 全局事件总线,所有场景均可访问
// 场景A触发事件:
this.game.events.emit('score-changed', this.score);
// 场景B监听事件:
this.game.events.on('score-changed', (score) => { this.scoreText.setText(score); });

// 方法2:this.registry — 所有场景共享的DataManager
// registry是Game实例上的Phaser.Data.DataManager
// 场景A设置数据:
this.registry.set('score', 100);
// 场景B监听数据变化:
this.registry.events.on('changedata-score', (parent, value, previousValue) => {
    this.scoreText.setText(value);
});

// 方法3:通过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);
});
js
// 触发自定义事件并传递任意数据参数
this.events.emit('player-died', this.player, { lives: this.lives });
this.events.on('player-died', (player, data) => {
    console.log('剩余生命:', data.lives);
});

All Event Namespaces Reference

所有事件命名空间参考

Scene Events (
Phaser.Scenes.Events
)

场景事件(
Phaser.Scenes.Events

Emitter:
this.events
(the Scene's Systems EventEmitter)
ConstantStringWhen
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
事件发射器:
this.events
(场景的Systems EventEmitter)
常量字符串触发时机
BOOT
'boot'
场景Systems启动(供插件使用)
READY
'ready'
场景Systems完全就绪
START
'start'
场景开始运行
CREATE
'create'
Scene.create()执行完成后
PRE_UPDATE
'preupdate'
每帧update之前
UPDATE
'update'
每帧主update阶段
POST_UPDATE
'postupdate'
每帧update之后
PRE_RENDER
'prerender'
每帧渲染之前
RENDER
'render'
每帧渲染阶段
PAUSE
'pause'
场景暂停
RESUME
'resume'
场景从暂停恢复
SLEEP
'sleep'
场景进入休眠
WAKE
'wake'
场景从休眠唤醒
SHUTDOWN
'shutdown'
场景正在关闭(可能会重启)
DESTROY
'destroy'
场景被永久销毁
ADDED_TO_SCENE
'addedtoscene'
游戏对象被添加到场景
REMOVED_FROM_SCENE
'removedfromscene'
游戏对象从场景移除
TRANSITION_INIT
'transitioninit'
转场初始化(目标场景)
TRANSITION_START
'transitionstart'
转场开始(目标场景)
TRANSITION_OUT
'transitionout'
转场退出(源场景)
TRANSITION_COMPLETE
'transitioncomplete'
转场完成
TRANSITION_WAKE
'transitionwake'
转场唤醒目标场景

Game Events (
Phaser.Core.Events
)

游戏事件(
Phaser.Core.Events

Emitter:
this.game.events
or
game.events
ConstantStringWhen
BOOT
'boot'
Game instance finished booting
READY
'ready'
Game ready to start running
SYSTEM_READY
'systemready'
All global systems ready
PRE_STEP
'prestep'
Before game loop step
STEP
'step'
Main game loop step
POST_STEP
'poststep'
After game loop step
PRE_RENDER
'prerender'
Before rendering all scenes
POST_RENDER
'postrender'
After rendering all scenes
PAUSE
'pause'
Game paused
RESUME
'resume'
Game resumed
BLUR
'blur'
Browser tab lost focus
FOCUS
'focus'
Browser tab gained focus
HIDDEN
'hidden'
Page Visibility API: hidden
VISIBLE
'visible'
Page Visibility API: visible
CONTEXT_LOST
'contextlost'
WebGL context lost
DESTROY
'destroy'
Game being destroyed
事件发射器:
this.game.events
game.events
常量字符串触发时机
BOOT
'boot'
Game实例启动完成
READY
'ready'
Game准备好开始运行
SYSTEM_READY
'systemready'
所有全局系统就绪
PRE_STEP
'prestep'
游戏循环步骤之前
STEP
'step'
游戏循环主步骤
POST_STEP
'poststep'
游戏循环步骤之后
PRE_RENDER
'prerender'
渲染所有场景之前
POST_RENDER
'postrender'
渲染所有场景之后
PAUSE
'pause'
游戏暂停
RESUME
'resume'
游戏恢复
BLUR
'blur'
浏览器标签失去焦点
FOCUS
'focus'
浏览器标签获得焦点
HIDDEN
'hidden'
Page Visibility API:页面隐藏
VISIBLE
'visible'
Page Visibility API:页面可见
CONTEXT_LOST
'contextlost'
WebGL上下文丢失
DESTROY
'destroy'
Game正在被销毁

Input Events (
Phaser.Input.Events
)

输入事件(
Phaser.Input.Events

Emitter:
this.input
(scene-level) or individual GameObjects. Events exist at three levels: scene-level (
this.input
), scene-level with gameobject prefix, and directly on interactive GameObjects. See ../input-keyboard-mouse-touch/SKILL.md for full usage.
Scene-level pointer events (on
this.input
):
POINTER_DOWN
'pointerdown'
|
POINTER_UP
'pointerup'
|
POINTER_MOVE
'pointermove'
|
POINTER_OVER
'pointerover'
|
POINTER_OUT
'pointerout'
|
POINTER_WHEEL
'wheel'
|
POINTER_DOWN_OUTSIDE
'pointerdownoutside'
|
POINTER_UP_OUTSIDE
'pointerupoutside'
Scene-level gameobject events (on
this.input
):
GAMEOBJECT_DOWN
'gameobjectdown'
|
GAMEOBJECT_UP
'gameobjectup'
|
GAMEOBJECT_MOVE
'gameobjectmove'
|
GAMEOBJECT_OVER
'gameobjectover'
|
GAMEOBJECT_OUT
'gameobjectout'
|
GAMEOBJECT_WHEEL
'gameobjectwheel'
Per-GameObject events (emitted on the GameObject itself, requires
setInteractive()
):
GAMEOBJECT_POINTER_DOWN
'pointerdown'
|
GAMEOBJECT_POINTER_UP
'pointerup'
|
GAMEOBJECT_POINTER_MOVE
'pointermove'
|
GAMEOBJECT_POINTER_OVER
'pointerover'
|
GAMEOBJECT_POINTER_OUT
'pointerout'
|
GAMEOBJECT_POINTER_WHEEL
'wheel'
Drag events (on
this.input
and on GameObjects with same string):
DRAG_START
/
GAMEOBJECT_DRAG_START
'dragstart'
|
DRAG
/
GAMEOBJECT_DRAG
'drag'
|
DRAG_END
/
GAMEOBJECT_DRAG_END
'dragend'
|
DRAG_ENTER
/
GAMEOBJECT_DRAG_ENTER
'dragenter'
|
DRAG_OVER
/
GAMEOBJECT_DRAG_OVER
'dragover'
|
DRAG_LEAVE
/
GAMEOBJECT_DRAG_LEAVE
'dragleave'
|
DROP
/
GAMEOBJECT_DROP
'drop'
Other:
GAME_OUT
'gameout'
|
GAME_OVER
'gameover'
|
POINTERLOCK_CHANGE
'pointerlockchange'
事件发射器:
this.input
(场景级)或单个游戏对象。事件分为三个层级:场景级(
this.input
)、带游戏对象前缀的场景级、直接在可交互游戏对象上触发。完整用法请参考../input-keyboard-mouse-touch/SKILL.md。
场景级指针事件(
this.input
上):
POINTER_DOWN
'pointerdown'
|
POINTER_UP
'pointerup'
|
POINTER_MOVE
'pointermove'
|
POINTER_OVER
'pointerover'
|
POINTER_OUT
'pointerout'
|
POINTER_WHEEL
'wheel'
|
POINTER_DOWN_OUTSIDE
'pointerdownoutside'
|
POINTER_UP_OUTSIDE
'pointerupoutside'
场景级游戏对象事件(
this.input
上):
GAMEOBJECT_DOWN
'gameobjectdown'
|
GAMEOBJECT_UP
'gameobjectup'
|
GAMEOBJECT_MOVE
'gameobjectmove'
|
GAMEOBJECT_OVER
'gameobjectover'
|
GAMEOBJECT_OUT
'gameobjectout'
|
GAMEOBJECT_WHEEL
'gameobjectwheel'
单个游戏对象事件(在游戏对象自身触发,需调用
setInteractive()
):
GAMEOBJECT_POINTER_DOWN
'pointerdown'
|
GAMEOBJECT_POINTER_UP
'pointerup'
|
GAMEOBJECT_POINTER_MOVE
'pointermove'
|
GAMEOBJECT_POINTER_OVER
'pointerover'
|
GAMEOBJECT_POINTER_OUT
'pointerout'
|
GAMEOBJECT_POINTER_WHEEL
'wheel'
拖拽事件(
this.input
和游戏对象上均有相同字符串):
DRAG_START
/
GAMEOBJECT_DRAG_START
'dragstart'
|
DRAG
/
GAMEOBJECT_DRAG
'drag'
|
DRAG_END
/
GAMEOBJECT_DRAG_END
'dragend'
|
DRAG_ENTER
/
GAMEOBJECT_DRAG_ENTER
'dragenter'
|
DRAG_OVER
/
GAMEOBJECT_DRAG_OVER
'dragover'
|
DRAG_LEAVE
/
GAMEOBJECT_DRAG_LEAVE
'dragleave'
|
DROP
/
GAMEOBJECT_DROP
'drop'
其他:
GAME_OUT
'gameout'
|
GAME_OVER
'gameover'
|
POINTERLOCK_CHANGE
'pointerlockchange'

Loader Events (
Phaser.Loader.Events
)

加载器事件(
Phaser.Loader.Events

Emitter:
this.load
ConstantStringWhen
ADD
'addfile'
File added to load queue
START
'start'
Loader starts
PROGRESS
'progress'
Overall progress updated (0-1)
FILE_LOAD
'load'
Individual file loaded
FILE_PROGRESS
'fileprogress'
Individual file progress
FILE_COMPLETE
'filecomplete'
Individual file completed processing
FILE_KEY_COMPLETE
'filecomplete-'
Specific file completed (append
type-key
)
FILE_LOAD_ERROR
'loaderror'
File failed to load
POST_PROCESS
'postprocess'
All files loaded, post-processing
COMPLETE
'complete'
All loading complete
事件发射器:
this.load
常量字符串触发时机
ADD
'addfile'
文件被添加到加载队列
START
'start'
加载器开始运行
PROGRESS
'progress'
整体加载进度更新(0-1)
FILE_LOAD
'load'
单个文件加载完成
FILE_PROGRESS
'fileprogress'
单个文件加载进度更新
FILE_COMPLETE
'filecomplete'
单个文件处理完成
FILE_KEY_COMPLETE
'filecomplete-'
特定文件处理完成(追加
type-key
FILE_LOAD_ERROR
'loaderror'
文件加载失败
POST_PROCESS
'postprocess'
所有文件加载完成,进入后处理阶段
COMPLETE
'complete'
所有加载完成

Animation Events (
Phaser.Animations.Events
)

动画事件(
Phaser.Animations.Events

Emitter: individual sprites (per-sprite) or
this.anims
(global AnimationManager)
ConstantStringWhen
ADD_ANIMATION
'add'
Animation added to manager
REMOVE_ANIMATION
'remove'
Animation removed from manager
PAUSE_ALL
'pauseall'
All animations paused
RESUME_ALL
'resumeall'
All animations resumed
ANIMATION_START
'animationstart'
Animation starts playing on a sprite
ANIMATION_RESTART
'animationrestart'
Animation restarts on a sprite
ANIMATION_REPEAT
'animationrepeat'
Animation repeats on a sprite
ANIMATION_UPDATE
'animationupdate'
Animation frame changes on a sprite
ANIMATION_COMPLETE
'animationcomplete'
Animation finishes on a sprite
ANIMATION_COMPLETE_KEY
'animationcomplete-'
Specific animation finishes (append key)
ANIMATION_STOP
'animationstop'
Animation stopped on a sprite
事件发射器:单个精灵(每个精灵独立)或
this.anims
(全局AnimationManager)
常量字符串触发时机
ADD_ANIMATION
'add'
动画被添加到管理器
REMOVE_ANIMATION
'remove'
动画从管理器移除
PAUSE_ALL
'pauseall'
所有动画暂停
RESUME_ALL
'resumeall'
所有动画恢复
ANIMATION_START
'animationstart'
精灵上的动画开始播放
ANIMATION_RESTART
'animationrestart'
精灵上的动画重新播放
ANIMATION_REPEAT
'animationrepeat'
精灵上的动画重复播放
ANIMATION_UPDATE
'animationupdate'
精灵上的动画帧更新
ANIMATION_COMPLETE
'animationcomplete'
精灵上的动画播放完成
ANIMATION_COMPLETE_KEY
'animationcomplete-'
特定动画播放完成(追加键名)
ANIMATION_STOP
'animationstop'
精灵上的动画停止播放

Camera Events (
Phaser.Cameras.Scene2D.Events
)

相机事件(
Phaser.Cameras.Scene2D.Events

Emitter: individual camera instance (e.g.
this.cameras.main
). Each camera effect has a START and COMPLETE pair.
DESTROY
'cameradestroy'
|
FADE_IN_START
'camerafadeinstart'
|
FADE_IN_COMPLETE
'camerafadeincomplete'
|
FADE_OUT_START
'camerafadeoutstart'
|
FADE_OUT_COMPLETE
'camerafadeoutcomplete'
|
FLASH_START
'cameraflashstart'
|
FLASH_COMPLETE
'cameraflashcomplete'
|
PAN_START
'camerapanstart'
|
PAN_COMPLETE
'camerapancomplete'
|
ROTATE_START
'camerarotatestart'
|
ROTATE_COMPLETE
'camerarotatecomplete'
|
SHAKE_START
'camerashakestart'
|
SHAKE_COMPLETE
'camerashakecomplete'
|
ZOOM_START
'camerazoomstart'
|
ZOOM_COMPLETE
'camerazoomcomplete'
|
FOLLOW_UPDATE
'followupdate'
|
PRE_RENDER
'prerender'
|
POST_RENDER
'postrender'
事件发射器:单个相机实例(例如
this.cameras.main
)。每个相机特效都有对应的START和COMPLETE事件对。
DESTROY
'cameradestroy'
|
FADE_IN_START
'camerafadeinstart'
|
FADE_IN_COMPLETE
'camerafadeincomplete'
|
FADE_OUT_START
'camerafadeoutstart'
|
FADE_OUT_COMPLETE
'camerafadeoutcomplete'
|
FLASH_START
'cameraflashstart'
|
FLASH_COMPLETE
'cameraflashcomplete'
|
PAN_START
'camerapanstart'
|
PAN_COMPLETE
'camerapancomplete'
|
ROTATE_START
'camerarotatestart'
|
ROTATE_COMPLETE
'camerarotatecomplete'
|
SHAKE_START
'camerashakestart'
|
SHAKE_COMPLETE
'camerashakecomplete'
|
ZOOM_START
'camerazoomstart'
|
ZOOM_COMPLETE
'camerazoomcomplete'
|
FOLLOW_UPDATE
'followupdate'
|
PRE_RENDER
'prerender'
|
POST_RENDER
'postrender'

Sound Events (
Phaser.Sound.Events
)

声音事件(
Phaser.Sound.Events

Emitter: individual sound instances or
this.sound
(SoundManager)
Per-sound instance events:
PLAY
'play'
|
PAUSE
'pause'
|
RESUME
'resume'
|
STOP
'stop'
|
COMPLETE
'complete'
|
LOOP
'loop'
|
LOOPED
'looped'
|
SEEK
'seek'
|
MUTE
'mute'
|
VOLUME
'volume'
|
RATE
'rate'
|
DETUNE
'detune'
|
PAN
'pan'
|
DECODED
'decoded'
|
DESTROY
'destroy'
SoundManager-level events (on
this.sound
):
GLOBAL_MUTE
'mute'
|
GLOBAL_VOLUME
'volume'
|
GLOBAL_RATE
'rate'
|
GLOBAL_DETUNE
'detune'
|
PAUSE_ALL
'pauseall'
|
RESUME_ALL
'resumeall'
|
STOP_ALL
'stopall'
|
DECODED_ALL
'decodedall'
|
UNLOCKED
'unlocked'
事件发射器:单个声音实例或
this.sound
(SoundManager)
单个声音实例事件:
PLAY
'play'
|
PAUSE
'pause'
|
RESUME
'resume'
|
STOP
'stop'
|
COMPLETE
'complete'
|
LOOP
'loop'
|
LOOPED
'looped'
|
SEEK
'seek'
|
MUTE
'mute'
|
VOLUME
'volume'
|
RATE
'rate'
|
DETUNE
'detune'
|
PAN
'pan'
|
DECODED
'decoded'
|
DESTROY
'destroy'
SoundManager级事件(
this.sound
上):
GLOBAL_MUTE
'mute'
|
GLOBAL_VOLUME
'volume'
|
GLOBAL_RATE
'rate'
|
GLOBAL_DETUNE
'detune'
|
PAUSE_ALL
'pauseall'
|
RESUME_ALL
'resumeall'
|
STOP_ALL
'stopall'
|
DECODED_ALL
'decodedall'
|
UNLOCKED
'unlocked'

Tween Events (
Phaser.Tweens.Events
)

补间事件(
Phaser.Tweens.Events

Emitter: individual tween instances
ConstantStringWhen
TWEEN_ACTIVE
'active'
Tween becomes active
TWEEN_START
'start'
Tween starts first play
TWEEN_UPDATE
'update'
Tween updates a value
TWEEN_YOYO
'yoyo'
Tween yoyos (reverses direction)
TWEEN_REPEAT
'repeat'
Tween repeats
TWEEN_LOOP
'loop'
Tween loops
TWEEN_PAUSE
'pause'
Tween paused
TWEEN_RESUME
'resume'
Tween resumed
TWEEN_COMPLETE
'complete'
Tween finishes
TWEEN_STOP
'stop'
Tween stopped manually
事件发射器:单个补间实例
常量字符串触发时机
TWEEN_ACTIVE
'active'
补间变为激活状态
TWEEN_START
'start'
补间首次开始播放
TWEEN_UPDATE
'update'
补间更新数值
TWEEN_YOYO
'yoyo'
补间反向播放
TWEEN_REPEAT
'repeat'
补间重复播放
TWEEN_LOOP
'loop'
补间循环播放
TWEEN_PAUSE
'pause'
补间暂停
TWEEN_RESUME
'resume'
补间恢复
TWEEN_COMPLETE
'complete'
补间播放完成
TWEEN_STOP
'stop'
补间被手动停止

Arcade Physics Events (
Phaser.Physics.Arcade.Events
)

街机物理事件(
Phaser.Physics.Arcade.Events

Emitter:
this.physics.world
ConstantStringWhen
COLLIDE
'collide'
Two bodies collide
OVERLAP
'overlap'
Two bodies overlap
TILE_COLLIDE
'tilecollide'
Body collides with a tile
TILE_OVERLAP
'tileoverlap'
Body overlaps with a tile
WORLD_BOUNDS
'worldbounds'
Body hits world boundary
WORLD_STEP
'worldstep'
Physics world completes a step
PAUSE
'pause'
Physics world paused
RESUME
'resume'
Physics world resumed
事件发射器:
this.physics.world
常量字符串触发时机
COLLIDE
'collide'
两个物体碰撞
OVERLAP
'overlap'
两个物体重叠
TILE_COLLIDE
'tilecollide'
物体与瓦片碰撞
TILE_OVERLAP
'tileoverlap'
物体与瓦片重叠
WORLD_BOUNDS
'worldbounds'
物体碰撞到世界边界
WORLD_STEP
'worldstep'
物理世界完成一次步进
PAUSE
'pause'
物理世界暂停
RESUME
'resume'
物理世界恢复

Texture Events (
Phaser.Textures.Events
)

纹理事件(
Phaser.Textures.Events

Emitter:
this.textures
(TextureManager)
ConstantStringWhen
ADD
'addtexture'
Any texture added
ADD_KEY
'addtexture-'
Specific texture added (append key)
REMOVE
'removetexture'
Any texture removed
REMOVE_KEY
'removetexture-'
Specific texture removed (append key)
LOAD
'onload'
Texture source loaded
ERROR
'onerror'
Texture source load error
READY
'ready'
Texture manager ready
事件发射器:
this.textures
(TextureManager)
常量字符串触发时机
ADD
'addtexture'
任意纹理被添加
ADD_KEY
'addtexture-'
特定纹理被添加(追加键名)
REMOVE
'removetexture'
任意纹理被移除
REMOVE_KEY
'removetexture-'
特定纹理被移除(追加键名)
LOAD
'onload'
纹理资源加载完成
ERROR
'onerror'
纹理资源加载失败
READY
'ready'
纹理管理器就绪

GameObject Events (
Phaser.GameObjects.Events
)

游戏对象事件(
Phaser.GameObjects.Events

Emitter: individual GameObjects
ConstantStringWhen
ADDED_TO_SCENE
'addedtoscene'
GameObject added to a scene
REMOVED_FROM_SCENE
'removedfromscene'
GameObject removed from scene
DESTROY
'destroy'
GameObject destroyed
Video GameObject events (on Video GameObjects):
VIDEO_PLAY
'play'
|
VIDEO_PLAYING
'playing'
|
VIDEO_COMPLETE
'complete'
|
VIDEO_LOOP
'loop'
|
VIDEO_STOP
'stop'
|
VIDEO_CREATED
'created'
|
VIDEO_ERROR
'error'
|
VIDEO_LOCKED
'locked'
|
VIDEO_UNLOCKED
'unlocked'
|
VIDEO_METADATA
'metadata'
|
VIDEO_SEEKED
'seeked'
|
VIDEO_SEEKING
'seeking'
|
VIDEO_STALLED
'stalled'
|
VIDEO_TEXTURE
'textureready'
|
VIDEO_UNSUPPORTED
'unsupported'
事件发射器:单个游戏对象
常量字符串触发时机
ADDED_TO_SCENE
'addedtoscene'
游戏对象被添加到场景
REMOVED_FROM_SCENE
'removedfromscene'
游戏对象从场景移除
DESTROY
'destroy'
游戏对象被销毁
视频游戏对象事件(在Video游戏对象上):
VIDEO_PLAY
'play'
|
VIDEO_PLAYING
'playing'
|
VIDEO_COMPLETE
'complete'
|
VIDEO_LOOP
'loop'
|
VIDEO_STOP
'stop'
|
VIDEO_CREATED
'created'
|
VIDEO_ERROR
'error'
|
VIDEO_LOCKED
'locked'
|
VIDEO_UNLOCKED
'unlocked'
|
VIDEO_METADATA
'metadata'
|
VIDEO_SEEKED
'seeked'
|
VIDEO_SEEKING
'seeking'
|
VIDEO_STALLED
'stalled'
|
VIDEO_TEXTURE
'textureready'
|
VIDEO_UNSUPPORTED
'unsupported'

Time Events (
Phaser.Time.Events
)

时间事件(
Phaser.Time.Events

Emitter:
Phaser.Time.TimerEvent
instances
ConstantStringWhen
COMPLETE
'complete'
TimerEvent finishes all repeats
事件发射器:
Phaser.Time.TimerEvent
实例
常量字符串触发时机
COMPLETE
'complete'
TimerEvent完成所有重复次数

Event Removal Safety

事件移除注意事项

You must pass the SAME function reference AND the same context/scope to
off()
that you used with
on()
. Anonymous or inline arrow functions cannot be removed.
js
// BAD: arrow function cannot be removed later
this.events.on('update', () => { this.doStuff(); });

// GOOD: named method can be removed
this.events.on('update', this.onUpdate, this);
this.events.off('update', this.onUpdate, this);
调用
off()
时必须传入与
on()
完全相同的函数引用和上下文/作用域。匿名函数或内联箭头函数无法被移除。
js
// 错误:箭头函数无法被后续移除
this.events.on('update', () => { this.doStuff(); });

// 正确:命名方法可以被移除
this.events.on('update', this.onUpdate, this);
this.events.off('update', this.onUpdate, this);

once() Auto-Removes

once()自动移除

once()
automatically removes the listener after first fire. No manual cleanup needed.
js
this.events.once(Phaser.Scenes.Events.CREATE, this.onFirstCreate, this);
once()
会在事件首次触发后自动移除监听器,无需手动清理。
js
this.events.once(Phaser.Scenes.Events.CREATE, this.onFirstCreate, this);

Utility Methods

工具方法

js
emitter.listenerCount('update');          // number of listeners for an event
emitter.eventNames();                      // ['update', 'player-died'] -- all registered event names
emitter.removeAllListeners('player-died'); // remove all listeners for one event
emitter.removeAllListeners();              // remove ALL listeners for ALL events
js
emitter.listenerCount('update');          // 获取某个事件的监听器数量
emitter.eventNames();                      // ['update', 'player-died'] -- 所有已注册的事件名称
emitter.removeAllListeners('player-died'); // 移除某个事件的所有监听器
emitter.removeAllListeners();              // 移除所有事件的所有监听器

Creating a Standalone EventEmitter

创建独立的EventEmitter

js
const bus = new Phaser.Events.EventEmitter();
bus.on('inventory-changed', (items) => { console.log(items.length); });
bus.emit('inventory-changed', this.inventory);
js
const bus = new Phaser.Events.EventEmitter();
bus.on('inventory-changed', (items) => { console.log(items.length); });
bus.emit('inventory-changed', this.inventory);

Scene Events vs Game Events

场景事件 vs 游戏事件

  • this.events
    -- Scene-specific. Fires scene lifecycle events. Cleaned up when scene is destroyed.
  • this.game.events
    -- Global. Fires game-level events (blur, focus, pause, resume). Persists across scene restarts -- clean up on SHUTDOWN.
js
create() {
    this.events.on(Phaser.Scenes.Events.UPDATE, this.onUpdate, this);
    this.game.events.on(Phaser.Core.Events.BLUR, this.onBlur, this);
    this.events.once(Phaser.Scenes.Events.SHUTDOWN, () => {
        this.game.events.off(Phaser.Core.Events.BLUR, this.onBlur, this);
    });
}
  • this.events
    -- 场景专属,触发场景生命周期事件,场景销毁时会被清理。
  • this.game.events
    -- 全局事件,触发游戏级事件(失焦、聚焦、暂停、恢复),会在场景重启后保留,需在SHUTDOWN时清理。
js
create() {
    this.events.on(Phaser.Scenes.Events.UPDATE, this.onUpdate, this);
    this.game.events.on(Phaser.Core.Events.BLUR, this.onBlur, this);
    this.events.once(Phaser.Scenes.Events.SHUTDOWN, () => {
        this.game.events.off(Phaser.Core.Events.BLUR, this.onBlur, this);
    });
}

Gotchas

注意事项

Memory Leaks from Unremoved Listeners

未移除监听器导致的内存泄漏

The most common source of bugs. If a scene uses
on()
and the scene restarts via
scene.restart()
, old listeners persist because
on()
does not auto-remove. Each restart adds duplicate listeners.
js
// BAD: leaks listeners on every scene restart
create() {
    this.input.on('pointerdown', this.shoot, this);
}

// GOOD: clean up in shutdown
create() {
    this.input.on('pointerdown', this.shoot, this);
    this.events.once(Phaser.Scenes.Events.SHUTDOWN, () => {
        this.input.off('pointerdown', this.shoot, this);
    });
}

// ALSO GOOD: use once() for events you only need fired once
create() {
    this.events.once(Phaser.Scenes.Events.CREATE, this.onFirstCreate, this);
}
这是最常见的bug来源。如果场景使用
on()
且通过
scene.restart()
重启,旧的监听器会保留,因为
on()
不会自动移除,每次重启都会添加重复的监听器。
js
// 错误:每次场景重启都会泄漏监听器
create() {
    this.input.on('pointerdown', this.shoot, this);
}

// 正确:在shutdown时清理
create() {
    this.input.on('pointerdown', this.shoot, this);
    this.events.once(Phaser.Scenes.Events.SHUTDOWN, () => {
        this.input.off('pointerdown', this.shoot, this);
    });
}

// 同样正确:使用once()监听只需触发一次的事件
create() {
    this.events.once(Phaser.Scenes.Events.CREATE, this.onFirstCreate, this);
}

shutdown vs destroy

shutdown vs destroy

  • SHUTDOWN
    fires when a scene stops but can restart later. Clean up listeners here.
  • DESTROY
    fires when a scene is permanently removed. Use for final cleanup.
  • A scene restart fires
    SHUTDOWN
    then
    START
    then
    CREATE
    . It does NOT fire
    DESTROY
    .
  • SHUTDOWN
    在场景停止但可能后续重启时触发,在此处清理监听器。
  • DESTROY
    在场景被永久移除时触发,用于最终清理。
  • 场景重启会触发
    SHUTDOWN
    ,然后是
    START
    CREATE
    ,不会触发
    DESTROY

Context Binding

上下文绑定

The third argument to
on
/
once
sets
this
inside the callback. Without it,
this
defaults to the emitter, not the scene. Use
this
as the third argument with regular functions, or use arrow functions (which capture lexical
this
).
on
/
once
的第三个参数设置回调内部的
this
指向。如果不设置,
this
默认指向事件发射器而非场景。普通函数使用
this
作为第三个参数,或使用箭头函数(捕获词法作用域的
this
)。

off() Requires Exact References

off()需要精确引用

off()
only works if you pass the exact same function reference (and context) used with
on()
. Anonymous functions or arrow literals cannot be removed -- store a reference or use a class method.
off()
仅在传入与
on()
完全相同的函数引用(和上下文)时生效。匿名函数或箭头字面量无法被移除——请存储函数引用或使用类方法。

Input Event Hierarchy

输入事件层级

Input events fire in order: (1)
GAMEOBJECT_POINTER_DOWN
on the GameObject, (2)
GAMEOBJECT_DOWN
on
this.input
, (3)
POINTER_DOWN
on
this.input
. Higher handlers can stop propagation.
输入事件触发顺序:(1) 游戏对象上的
GAMEOBJECT_POINTER_DOWN
,(2)
this.input
上的
GAMEOBJECT_DOWN
,(3)
this.input
上的
POINTER_DOWN
。上层处理函数可以阻止事件传播。

Game Events vs Scene Events

游戏事件 vs 场景事件

this.game.events
and
this.events
are different emitters. Game events fire once per game loop tick across all scenes. Scene events fire per-scene. Listeners on
game.events
persist across scene restarts -- always clean them up on SHUTDOWN:
js
create() {
    this.game.events.on(Phaser.Core.Events.BLUR, this.onBlur, this);
    this.events.once(Phaser.Scenes.Events.SHUTDOWN, () => {
        this.game.events.off(Phaser.Core.Events.BLUR, this.onBlur, this);
    });
}
this.game.events
this.events
是不同的事件发射器。游戏事件在每个游戏循环 tick 中触发一次,所有场景共享;场景事件按每个场景触发。
game.events
上的监听器会在场景重启后保留——务必在SHUTDOWN时清理:
js
create() {
    this.game.events.on(Phaser.Core.Events.BLUR, this.onBlur, this);
    this.events.once(Phaser.Scenes.Events.SHUTDOWN, () => {
        this.game.events.off(Phaser.Core.Events.BLUR, this.onBlur, this);
    });
}

Source File Map

源码文件映射

PathDescription
src/events/EventEmitter.js
Base EventEmitter class (wraps eventemitter3)
src/scene/events/
Scene lifecycle events (22 events)
src/core/events/
Game-level events (16 events)
src/input/events/
Input/pointer/drag events (48 events)
src/loader/events/
Asset loading events (10 events)
src/animations/events/
Animation playback events (11 events)
src/cameras/2d/events/
Camera effect events (18 events)
src/sound/events/
Sound playback events (24 events)
src/tweens/events/
Tween lifecycle events (10 events)
src/physics/arcade/events/
Arcade physics events (8 events)
src/textures/events/
Texture manager events (7 events)
src/gameobjects/events/
GameObject lifecycle + Video events (18 events)
src/time/events/
TimerEvent events (1 event)
路径描述
src/events/EventEmitter.js
基础EventEmitter类(封装eventemitter3)
src/scene/events/
场景生命周期事件(22个事件)
src/core/events/
游戏级事件(16个事件)
src/input/events/
输入/指针/拖拽事件(48个事件)
src/loader/events/
资源加载事件(10个事件)
src/animations/events/
动画播放事件(11个事件)
src/cameras/2d/events/
相机特效事件(18个事件)
src/sound/events/
声音播放事件(24个事件)
src/tweens/events/
补间生命周期事件(10个事件)
src/physics/arcade/events/
街机物理事件(8个事件)
src/textures/events/
纹理管理器事件(7个事件)
src/gameobjects/events/
游戏对象生命周期 + 视频事件(18个事件)
src/time/events/
TimerEvent事件(1个事件)