phaser-core

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Phaser 3 Core

Phaser 3 核心指南

Set up the foundation of a Phaser 3 game: the
Game
config, the
Scene
lifecycle, asset loading, cameras, and passing data between scenes. Targets Phaser 3.90.
搭建Phaser 3游戏的基础框架:
Game
配置、
Scene
生命周期、资源加载、相机以及场景间的数据传递。针对Phaser 3.90版本。

When to use

适用场景

  • Use when starting a Phaser 3 game, wiring the
    Phaser.Game
    config, structuring
    Scene
    s, loading assets in
    preload
    , or fixing scene transitions and shared state.
  • Use when the project has
    phaser
    in
    package.json
    or
    import Phaser from 'phaser'
    , and code uses
    preload()
    /
    create()
    /
    update()
    .
When not to use: movement, velocity, colliders, gravity, or overlap → use
phaser-arcade-physics
. Complex rigid-body simulation uses Matter physics (a separate concern). For cross-engine save/load patterns use
save-systems
.
  • 适用于启动Phaser 3游戏、配置
    Phaser.Game
    、构建
    Scene
    结构、在
    preload
    中加载资源,或修复场景切换与共享状态问题时。
  • 适用于项目的
    package.json
    中包含
    phaser
    ,或代码中使用
    import Phaser from 'phaser'
    ,且代码调用了
    preload()
    /
    create()
    /
    update()
    的场景。
不适用场景:移动、速度、碰撞器、重力或重叠检测 → 请使用
phaser-arcade-physics
。复杂刚体模拟使用Matter物理引擎(独立模块)。跨引擎的保存/加载模式请使用
save-systems

Core workflow

核心工作流程

  1. Create the game from a config.
    new Phaser.Game(config)
    with
    type: Phaser.AUTO
    (WebGL with Canvas fallback), a
    width
    /
    height
    , and a
    scene
    array. The first scene (and any with
    active: true
    ) starts automatically.
  2. Model each screen as a
    Scene
    .
    Subclass
    Phaser.Scene
    , pass a unique
    key
    to
    super
    , and implement the lifecycle:
    init(data)
    preload()
    create(data)
    update(time, delta)
    .
  3. Load assets in
    preload
    , use them in
    create
    .
    Queued assets are not available until
    create
    . The loader is per-scene; the cache it fills is global.
  4. Reset per-run state in
    init()
    , not the constructor.
    A scene instance is reused across restarts, so constructor-set fields keep stale values.
  5. Move between screens with
    this.scene.start/launch/switch/sleep/wake
    . Share data through
    this.registry
    (global) or a sibling scene's event emitter.
  6. Run and observe. Serve the page, open it, and confirm assets load (watch the Network tab and console) and scenes switch as expected before assuming success.
  1. 通过配置创建游戏。使用
    new Phaser.Game(config)
    ,设置
    type: Phaser.AUTO
    (优先WebGL, fallback到Canvas)、
    width
    /
    height
    以及
    scene
    数组。第一个场景(以及所有设置
    active: true
    的场景)会自动启动。
  2. 将每个画面建模为
    Scene
    。继承
    Phaser.Scene
    ,向
    super
    传递唯一的
    key
    ,并实现生命周期方法:
    init(data)
    preload()
    create(data)
    update(time, delta)
  3. preload
    中加载资源,在
    create
    中使用
    。已排队的资源需等到
    create
    阶段才可使用。加载器为场景独有,但填充的缓存是全局的。
  4. init()
    中重置每次运行的状态,而非构造函数
    。场景实例会在重启时复用,因此构造函数中设置的字段会保留旧值。
  5. 通过
    this.scene.start/launch/switch/sleep/wake
    切换画面
    。通过
    this.registry
    (全局)或兄弟场景的事件发射器共享数据。
  6. 运行并观察。启动页面服务,打开页面,在确认资源加载成功(查看网络标签和控制台)且场景切换符合预期后,再判定操作成功。

Patterns

实践模式

1. Game config + boot (ES module)

1. 游戏配置 + 启动(ES模块)

js
// main.js — one Game owns the renderer, loop, cache, and Scene Manager.
import Phaser from 'phaser';
import BootScene from './scenes/BootScene.js';
import PlayScene from './scenes/PlayScene.js';

const config = {
  type: Phaser.AUTO,            // WebGL if available, else Canvas
  width: 800,
  height: 600,
  backgroundColor: '#1d1d28',
  scale: { mode: Phaser.Scale.FIT, autoCenter: Phaser.Scale.CENTER_BOTH },
  scene: [BootScene, PlayScene] // BootScene starts first
};

new Phaser.Game(config);
js
// main.js — 一个Game实例管理渲染器、循环、缓存和Scene管理器。
import Phaser from 'phaser';
import BootScene from './scenes/BootScene.js';
import PlayScene from './scenes/PlayScene.js';

const config = {
  type: Phaser.AUTO,            // 优先WebGL,否则使用Canvas
  width: 800,
  height: 600,
  backgroundColor: '#1d1d28',
  scale: { mode: Phaser.Scale.FIT, autoCenter: Phaser.Scale.CENTER_BOTH },
  scene: [BootScene, PlayScene] // BootScene首先启动
};

new Phaser.Game(config);

2. A Scene with the full lifecycle

2. 完整生命周期的Scene

js
// scenes/PlayScene.js
import Phaser from 'phaser';

export default class PlayScene extends Phaser.Scene {
  constructor() {
    super('play');                  // unique scene key
  }

  init(data) {
    // Reset run-specific state HERE so restarts start clean.
    this.score = 0;
    this.level = data.level ?? 1;
  }

  preload() {
    // Queue downloads. Not usable until create().
    this.load.image('player', 'assets/player.png');
    this.load.spritesheet('coin', 'assets/coin.png', { frameWidth: 16, frameHeight: 16 });
  }

  create() {
    this.player = this.add.sprite(400, 300, 'player');
    this.scoreText = this.add.text(10, 10, 'Score: 0', { fontSize: '20px', color: '#fff' });
    this.cursors = this.input.keyboard.createCursorKeys();
  }

  update(time, delta) {
    // delta is milliseconds since last frame; divide by 1000 for seconds.
    const speed = 200 * (delta / 1000);
    if (this.cursors.left.isDown)  this.player.x -= speed;
    if (this.cursors.right.isDown) this.player.x += speed;
  }
}
js
// scenes/PlayScene.js
import Phaser from 'phaser';

export default class PlayScene extends Phaser.Scene {
  constructor() {
    super('play');                  // 唯一的场景key
  }

  init(data) {
    // 在此处重置运行专属状态,确保重启时状态干净。
    this.score = 0;
    this.level = data.level ?? 1;
  }

  preload() {
    // 排队下载资源。需等到create()阶段才可使用。
    this.load.image('player', 'assets/player.png');
    this.load.spritesheet('coin', 'assets/coin.png', { frameWidth: 16, frameHeight: 16 });
  }

  create() {
    this.player = this.add.sprite(400, 300, 'player');
    this.scoreText = this.add.text(10, 10, 'Score: 0', { fontSize: '20px', color: '#fff' });
    this.cursors = this.input.keyboard.createCursorKeys();
  }

  update(time, delta) {
    // delta是自上一帧以来的毫秒数;除以1000转换为秒。
    const speed = 200 * (delta / 1000);
    if (this.cursors.left.isDown)  this.player.x -= speed;
    if (this.cursors.right.isDown) this.player.x += speed;
  }
}

3. Cross-scene data + events

3. 跨场景数据 + 事件

js
// The registry is a global DataManager shared by every scene.
this.registry.set('coins', 0);                 // in any scene
const coins = this.registry.get('coins');      // read anywhere

// React to registry changes (e.g. a HUD scene listening to gameplay):
this.registry.events.on('changedata-coins', (parent, value) => {
  this.coinText.setText(`Coins: ${value}`);
});

// Talk directly to another running scene via its event emitter:
const ui = this.scene.get('hud');
ui.events.emit('show-message', 'Level cleared!');
js
// registry是所有场景共享的全局DataManager。
this.registry.set('coins', 0);                 // 在任意场景中调用
const coins = this.registry.get('coins');      // 在任意位置读取

// 监听registry的变化(例如HUD场景监听游戏进程):
this.registry.events.on('changedata-coins', (parent, value) => {
  this.coinText.setText(`Coins: ${value}`);
});

// 通过事件发射器直接与另一个运行中的场景通信:
const ui = this.scene.get('hud');
ui.events.emit('show-message', 'Level cleared!');

4. Scene transitions (pick the right verb)

4. 场景切换(选择正确的方法)

js
this.scene.start('gameover', { score: this.score }); // stop this scene, start target
this.scene.launch('hud');        // run a second scene in parallel (overlay HUD)
this.scene.switch('menu');       // sleep this scene, start/wake target
this.scene.pause();              // freeze updates but keep rendering (modal)
this.scene.sleep();              // stop updating AND rendering, keep state for wake
js
this.scene.start('gameover', { score: this.score }); // 停止当前场景,启动目标场景
this.scene.launch('hud');        // 并行运行第二个场景(叠加HUD)
this.scene.switch('menu');       // 休眠当前场景,启动/唤醒目标场景
this.scene.pause();              // 冻结更新但保持渲染(模态框)
this.scene.sleep();              // 停止更新和渲染,保留状态以便唤醒

5. A camera that follows the player

5. 跟随玩家的相机

js
this.cameras.main.setBounds(0, 0, 1600, 1200);  // world size
this.cameras.main.startFollow(this.player, true, 0.1, 0.1); // smooth lerp follow
this.cameras.main.setZoom(1.5);
js
this.cameras.main.setBounds(0, 0, 1600, 1200);  // 世界尺寸
this.cameras.main.startFollow(this.player, true, 0.1, 0.1); // 平滑插值跟随
this.cameras.main.setZoom(1.5);

Pitfalls

常见陷阱

  • Assets are
    undefined
    in
    create
    /
    update
    → you forgot to queue them in
    preload
    , or used the wrong key. The loader runs between
    preload
    and
    create
    .
  • State leaks across a restart → you set fields in the constructor. The Scene instance is reused; reset run state in
    init()
    and clear arrays on
    shutdown
    .
  • this.scene.start
    vs
    this.scene.launch
    start
    stops the calling scene;
    launch
    runs the target alongside it. Using
    start
    for a HUD hides the game.
  • this
    is wrong in a callback
    → arrow functions keep the Scene's
    this
    ; plain
    function
    callbacks need a context argument or
    .bind(this)
    .
  • Phaser 2 tutorials don't work → "States" were renamed to "Scenes" in Phaser 3, and each Scene owns its own systems (input, cameras, tweens) rather than a global Game World.
  • Nothing renders / black screen → confirm the canvas mounted,
    width
    /
    height
    are set, and a scene actually started (check
    game.scene.dump()
    output).
  • create
    /
    update
    中资源为
    undefined
    → 你忘记在
    preload
    中排队资源,或使用了错误的key。加载器在
    preload
    create
    之间运行。
  • 重启后状态泄露 → 你在构造函数中设置了字段。场景实例会被复用;需在
    init()
    中重置运行状态,并在
    shutdown
    时清空数组。
  • this.scene.start
    vs
    this.scene.launch
    start
    会停止调用场景;
    launch
    会在当前场景旁运行目标场景。使用
    start
    加载HUD会隐藏游戏画面。
  • 回调中
    this
    指向错误
    → 箭头函数会保留Scene的
    this
    ;普通
    function
    回调需要上下文参数或
    .bind(this)
  • Phaser 2教程无法使用 → Phaser 3中“States”已重命名为“Scenes”,且每个Scene拥有自己的系统(输入、相机、补间),而非全局游戏世界。
  • 无渲染内容 / 黑屏 → 确认画布已挂载、
    width
    /
    height
    已设置,且确实有场景启动(查看
    game.scene.dump()
    的输出)。

References

参考资料

  • For the full scene state machine (pause/resume vs sleep/wake vs stop/start, the restart-state bug, and removing/replacing scenes), read
    references/scene-flow.md
    .
  • 如需了解完整的场景状态机(暂停/恢复 vs 休眠/唤醒 vs 停止/启动、重启状态bug以及移除/替换场景),请阅读
    references/scene-flow.md

Related skills

相关技能

  • phaser-arcade-physics
    — velocity, gravity, colliders, overlap, and groups.
  • input-systems
    — rebindable, multi-device input architecture (engine-agnostic).
  • pixijs-rendering
    /
    threejs-scene-setup
    — other browser rendering stacks.
  • platformer
    /
    puzzle
    — genre templates that compose Phaser skills.
  • phaser-arcade-physics
    — 速度、重力、碰撞器、重叠检测和组。
  • input-systems
    — 可重绑定的多设备输入架构(引擎无关)。
  • pixijs-rendering
    /
    threejs-scene-setup
    — 其他浏览器渲染栈。
  • platformer
    /
    puzzle
    — 组合Phaser技能的游戏类型模板。