Phaser 场景系统 #
场景概述 #
场景(Scene)是 Phaser 游戏的基本组织单元。每个场景都是一个独立的功能模块,可以包含自己的游戏对象、逻辑和资源。
text
┌─────────────────────────────────────────────────────────────┐
│ 游戏场景结构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ Game │
│ ├── BootScene 启动场景 │
│ ├── PreloadScene 资源加载场景 │
│ ├── MenuScene 菜单场景 │
│ ├── GameScene 游戏主场景 │
│ ├── UIScene UI 覆盖层场景 │
│ └── PauseScene 暂停场景 │
│ │
└─────────────────────────────────────────────────────────────┘
场景生命周期 #
完整生命周期 #
text
┌─────────────────────────────────────────────────────────────┐
│ 场景生命周期 │
├─────────────────────────────────────────────────────────────┤
│ │
│ new Scene() │
│ │ │
│ ▼ │
│ init(data) ◄── 初始化,接收数据 │
│ │ │
│ ▼ │
│ preload() ◄── 加载资源 │
│ │ │
│ ▼ │
│ create() ◄── 创建游戏对象 │
│ │ │
│ ▼ │
│ ┌────────────────┐ │
│ │ update() │ ◄── 游戏循环 │
│ │ ▲ │ │ │
│ │ └────┘ │ │
│ └────────────────┘ │
│ │ │
│ ▼ │
│ shutdown() ◄── 场景关闭清理 │
│ │ │
│ ▼ │
│ destroy() ◄── 场景销毁 │
│ │
└─────────────────────────────────────────────────────────────┘
生命周期详解 #
javascript
class GameScene extends Phaser.Scene {
constructor() {
super({ key: 'GameScene' });
console.log('1. Constructor');
}
init(data) {
console.log('2. Init - 接收数据:', data);
this.level = data.level || 1;
this.score = data.score || 0;
}
preload() {
console.log('3. Preload - 加载资源');
this.load.image('player', 'assets/player.png');
}
create() {
console.log('4. Create - 创建对象');
this.player = this.add.sprite(100, 100, 'player');
}
update(time, delta) {
console.log('5. Update - 游戏循环');
}
shutdown() {
console.log('6. Shutdown - 清理资源');
this.events.off('customEvent');
}
}
场景配置 #
基本配置 #
javascript
const config = {
key: 'GameScene',
active: false,
visible: true,
pack: {
files: []
}
};
class GameScene extends Phaser.Scene {
constructor() {
super(config);
}
}
配置选项 #
javascript
const sceneConfig = {
key: 'GameScene',
active: false,
visible: true,
pack: {
files: [
{ type: 'image', key: 'loading', url: 'loading.png' }
]
},
mapAdd: {
score: 0,
lives: 3
},
map: {
game: 'game',
anims: 'anims'
}
};
class GameScene extends Phaser.Scene {
constructor() {
super(sceneConfig);
}
}
使用装饰器风格(TypeScript) #
typescript
@sceneConfig({
key: 'GameScene'
})
class GameScene extends Phaser.Scene {
constructor() {
super({ key: 'GameScene' });
}
}
场景管理 #
场景管理器 #
javascript
const sceneManager = this.scene;
sceneManager.start('GameScene', { level: 1 });
sceneManager.stop('GameScene');
sceneManager.pause('GameScene');
sceneManager.resume('GameScene');
sceneManager.sleep('GameScene');
sceneManager.wake('GameScene');
sceneManager.switch('GameScene');
sceneManager.launch('UIScene');
sceneManager.remove('GameScene');
启动场景 #
javascript
this.scene.start('GameScene');
this.scene.start('GameScene', {
level: 2,
score: 1000
});
暂停与恢复 #
javascript
this.scene.pause('GameScene');
this.scene.resume('GameScene');
this.scene.pause();
this.scene.resume();
休眠与唤醒 #
javascript
this.scene.sleep('GameScene');
this.scene.sleep('GameScene', { data: 'value' });
this.scene.wake('GameScene');
this.scene.wake('GameScene', { data: 'value' });
停止与移除 #
javascript
this.scene.stop('GameScene');
this.scene.remove('GameScene');
切换场景 #
javascript
this.scene.switch('MenuScene');
this.scene.switch('GameScene');
并行运行场景 #
javascript
create() {
this.scene.launch('UIScene');
this.scene.launch('UIScene', { score: 100 });
}
场景间通信 #
使用事件系统 #
javascript
class GameScene extends Phaser.Scene {
create() {
this.score = 0;
this.events.on('collectStar', () => {
this.score += 10;
this.events.emit('scoreUpdate', this.score);
});
}
}
class UIScene extends Phaser.Scene {
create() {
const gameScene = this.scene.get('GameScene');
gameScene.events.on('scoreUpdate', (score) => {
this.scoreText.setText('Score: ' + score);
});
}
}
使用全局事件 #
javascript
class GameScene extends Phaser.Scene {
create() {
this.game.events.on('gameOver', (data) => {
console.log('Game Over!', data);
});
}
}
class UIScene extends Phaser.Scene {
showGameOver() {
this.game.events.emit('gameOver', { score: 1000 });
}
}
使用场景数据传递 #
javascript
class MenuScene extends Phaser.Scene {
startGame() {
this.scene.start('GameScene', {
level: 1,
difficulty: 'hard'
});
}
}
class GameScene extends Phaser.Scene {
init(data) {
this.level = data.level;
this.difficulty = data.difficulty;
}
}
使用共享数据对象 #
javascript
const gameState = {
score: 0,
lives: 3,
level: 1
};
class GameScene extends Phaser.Scene {
create() {
this.registry.set('gameState', gameState);
const state = this.registry.get('gameState');
state.score += 10;
}
}
class UIScene extends Phaser.Scene {
create() {
this.registry.events.on('changedata', (parent, key, value) => {
if (key === 'gameState') {
this.updateUI(value);
}
});
}
}
多场景协作 #
游戏场景 + UI 场景 #
javascript
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
scene: [GameScene, UIScene]
};
class GameScene extends Phaser.Scene {
constructor() {
super({ key: 'GameScene', active: true });
}
create() {
this.scene.launch('UIScene');
this.player = this.physics.add.sprite(400, 300, 'player');
this.events.on('scoreUpdate', (score) => {
this.registry.set('score', score);
});
}
}
class UIScene extends Phaser.Scene {
constructor() {
super({ key: 'UIScene', active: false });
}
create() {
this.scoreText = this.add.text(16, 16, 'Score: 0', {
fontSize: '32px',
fill: '#fff'
});
this.registry.events.on('changedata-score', (parent, value) => {
this.scoreText.setText('Score: ' + value);
});
}
}
场景层级管理 #
javascript
const config = {
scene: [
{ key: 'Boot', class: BootScene },
{ key: 'Preload', class: PreloadScene },
{ key: 'Menu', class: MenuScene },
{ key: 'Game', class: GameScene },
{ key: 'UI', class: UIScene },
{ key: 'Pause', class: PauseScene }
]
};
class BootScene extends Phaser.Scene {
create() {
this.scene.start('Preload');
}
}
class PreloadScene extends Phaser.Scene {
create() {
this.scene.start('Menu');
}
}
class MenuScene extends Phaser.Scene {
startGame() {
this.scene.start('Game');
}
}
class GameScene extends Phaser.Scene {
create() {
this.scene.launch('UI');
}
pause() {
this.scene.pause();
this.scene.launch('Pause');
}
}
class PauseScene extends Phaser.Scene {
resume() {
this.scene.stop();
this.scene.get('Game').scene.resume();
}
}
场景过渡效果 #
淡入淡出 #
javascript
class GameScene extends Phaser.Scene {
create() {
this.cameras.main.fadeIn(1000);
}
goToMenu() {
this.cameras.main.fadeOut(1000);
this.cameras.main.once('camerafadeoutcomplete', () => {
this.scene.start('MenuScene');
});
}
}
过渡动画 #
javascript
class GameScene extends Phaser.Scene {
transitionTo(sceneKey) {
this.cameras.main.fade(500, 0, 0, 0);
this.cameras.main.once('camerafadeoutcomplete', () => {
this.scene.start(sceneKey);
});
}
}
class MenuScene extends Phaser.Scene {
create() {
this.cameras.main.fadeIn(500);
this.cameras.main.once('camerafadeincomplete', () => {
console.log('Transition complete');
});
}
}
自定义过渡 #
javascript
class GameScene extends Phaser.Scene {
create() {
this.transitionOverlay = this.add.rectangle(
400, 300, 800, 600, 0x000000
);
this.transitionOverlay.setAlpha(0);
this.transitionOverlay.setDepth(1000);
}
transitionTo(sceneKey) {
this.tweens.add({
targets: this.transitionOverlay,
alpha: 1,
duration: 500,
onComplete: () => {
this.scene.start(sceneKey);
}
});
}
}
场景插件 #
注册场景插件 #
javascript
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
plugins: {
scene: [
{ key: 'MyPlugin', plugin: MyPlugin, mapping: 'myPlugin' }
]
},
scene: GameScene
};
class GameScene extends Phaser.Scene {
create() {
this.myPlugin.doSomething();
}
}
自定义场景插件 #
javascript
class MyPlugin extends Phaser.Plugins.ScenePlugin {
constructor(scene, pluginManager) {
super(scene, pluginManager, 'MyPlugin');
}
doSomething() {
console.log('Plugin method called in', this.scene.scene.key);
}
shutdown() {
console.log('Scene shutting down');
}
destroy() {
this.shutdown();
super.destroy();
}
}
场景最佳实践 #
场景职责分离 #
text
┌─────────────────────────────────────────────────────────────┐
│ 场景职责划分 │
├─────────────────────────────────────────────────────────────┤
│ │
│ BootScene │
│ ├── 加载必要的启动资源 │
│ └── 初始化游戏设置 │
│ │
│ PreloadScene │
│ ├── 加载所有游戏资源 │
│ └── 显示加载进度 │
│ │
│ MenuScene │
│ ├── 显示主菜单 │
│ └── 处理菜单交互 │
│ │
│ GameScene │
│ ├── 游戏主逻辑 │
│ └── 游戏对象管理 │
│ │
│ UIScene │
│ ├── 显示游戏 UI │
│ └── 处理 UI 交互 │
│ │
└─────────────────────────────────────────────────────────────┘
场景状态管理 #
javascript
class GameScene extends Phaser.Scene {
constructor() {
super({ key: 'GameScene' });
this.state = {
score: 0,
lives: 3,
level: 1,
paused: false
};
}
init(data) {
this.state.level = data.level || 1;
}
create() {
this.events.on('collectItem', (points) => {
this.state.score += points;
this.events.emit('stateChanged', this.state);
});
}
shutdown() {
this.events.removeAllListeners();
}
}
场景资源清理 #
javascript
class GameScene extends Phaser.Scene {
create() {
this.timer = this.time.addEvent({
delay: 1000,
callback: this.updateTimer,
callbackScope: this,
loop: true
});
this.input.keyboard.on('keydown-SPACE', this.jump, this);
this.events.on('customEvent', this.handleEvent, this);
}
shutdown() {
this.timer.remove();
this.input.keyboard.off('keydown-SPACE', this.jump, this);
this.events.off('customEvent', this.handleEvent, this);
}
}
完整示例 #
游戏场景流程 #
javascript
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
scene: [BootScene, PreloadScene, MenuScene, GameScene, UIScene]
};
class BootScene extends Phaser.Scene {
constructor() {
super({ key: 'BootScene' });
}
preload() {
this.load.image('logo', 'assets/logo.png');
}
create() {
this.scene.start('PreloadScene');
}
}
class PreloadScene extends Phaser.Scene {
constructor() {
super({ key: 'PreloadScene' });
}
preload() {
const progressBar = this.add.graphics();
const progressBox = this.add.graphics();
progressBox.fillStyle(0x222222, 0.8);
progressBox.fillRect(240, 270, 320, 50);
this.load.on('progress', (value) => {
progressBar.clear();
progressBar.fillStyle(0x00ff00, 1);
progressBar.fillRect(250, 280, 300 * value, 30);
});
this.load.image('sky', 'assets/sky.png');
this.load.image('ground', 'assets/platform.png');
this.load.spritesheet('dude', 'assets/dude.png', {
frameWidth: 32,
frameHeight: 48
});
}
create() {
this.scene.start('MenuScene');
}
}
class MenuScene extends Phaser.Scene {
constructor() {
super({ key: 'MenuScene' });
}
create() {
this.add.image(400, 300, 'sky');
const title = this.add.text(400, 200, 'My Game', {
fontSize: '64px',
fill: '#fff'
}).setOrigin(0.5);
const startButton = this.add.text(400, 400, 'Start Game', {
fontSize: '32px',
fill: '#fff',
backgroundColor: '#4CAF50',
padding: { x: 20, y: 10 }
}).setOrigin(0.5).setInteractive();
startButton.on('pointerdown', () => {
this.cameras.main.fadeOut(500);
this.cameras.main.once('camerafadeoutcomplete', () => {
this.scene.start('GameScene', { level: 1 });
});
});
}
}
class GameScene extends Phaser.Scene {
constructor() {
super({ key: 'GameScene' });
}
init(data) {
this.level = data.level || 1;
this.score = 0;
}
create() {
this.cameras.main.fadeIn(500);
this.scene.launch('UIScene');
this.add.image(400, 300, 'sky');
this.player = this.physics.add.sprite(100, 450, 'dude');
this.events.emit('scoreUpdate', this.score);
}
collectStar(player, star) {
star.destroy();
this.score += 10;
this.events.emit('scoreUpdate', this.score);
}
}
class UIScene extends Phaser.Scene {
constructor() {
super({ key: 'UIScene' });
}
create() {
this.scoreText = this.add.text(16, 16, 'Score: 0', {
fontSize: '32px',
fill: '#fff'
});
const gameScene = this.scene.get('GameScene');
gameScene.events.on('scoreUpdate', (score) => {
this.scoreText.setText('Score: ' + score);
});
}
}
下一步 #
现在你已经掌握了场景系统,接下来学习 游戏对象,深入了解 Phaser 中各种游戏对象的使用!
最后更新:2026-03-29