Phaser 插件系统 #

插件概述 #

Phaser 插件系统允许你扩展框架的功能,创建可复用的游戏组件。

text
┌─────────────────────────────────────────────────────────────┐
│                    插件类型                                  │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  Global Plugin(全局插件)                                  │
│  ├── 在整个游戏中可用                                      │
│  ├── 不绑定到特定场景                                      │
│  └── 适合全局功能                                          │
│                                                             │
│  Scene Plugin(场景插件)                                   │
│  ├── 绑定到特定场景                                        │
│  ├── 可以访问场景上下文                                    │
│  └── 适合场景相关功能                                      │
│                                                             │
└─────────────────────────────────────────────────────────────┘

全局插件 #

创建全局插件 #

javascript
class MyGlobalPlugin extends Phaser.Plugins.BasePlugin {
  constructor(pluginManager) {
    super('MyGlobalPlugin', pluginManager);
    
    this.data = {};
  }
  
  init() {
    console.log('Global plugin initialized');
  }
  
  start() {
    console.log('Global plugin started');
  }
  
  stop() {
    console.log('Global plugin stopped');
  }
  
  destroy() {
    console.log('Global plugin destroyed');
    this.data = null;
    super.destroy();
  }
  
  setData(key, value) {
    this.data[key] = value;
  }
  
  getData(key) {
    return this.data[key];
  }
}

注册全局插件 #

javascript
const config = {
  type: Phaser.AUTO,
  width: 800,
  height: 600,
  plugins: {
    global: [
      { key: 'MyGlobalPlugin', plugin: MyGlobalPlugin, start: true }
    ]
  }
};

const game = new Phaser.Game(config);

使用全局插件 #

javascript
const plugin = this.plugins.get('MyGlobalPlugin');

plugin.setData('score', 100);
const score = plugin.getData('score');

const plugin = this.plugins.start('MyGlobalPlugin');

场景插件 #

创建场景插件 #

javascript
class MyScenePlugin extends Phaser.Plugins.ScenePlugin {
  constructor(scene, pluginManager) {
    super(scene, pluginManager, 'MyScenePlugin');
    
    this.scene = scene;
    this.systems = scene.sys;
    
    this.data = {};
  }
  
  boot() {
    const eventEmitter = this.systems.events;
    
    eventEmitter.on('start', this.start, this);
    eventEmitter.on('shutdown', this.shutdown, this);
    eventEmitter.on('destroy', this.destroy, this);
  }
  
  start() {
    console.log('Scene plugin started for:', this.scene.scene.key);
  }
  
  shutdown() {
    console.log('Scene plugin shutdown');
    this.data = {};
  }
  
  destroy() {
    this.shutdown();
    super.destroy();
  }
  
  doSomething() {
    console.log('Doing something in scene:', this.scene.scene.key);
    return this;
  }
  
  addSprite(x, y, key) {
    return this.scene.add.sprite(x, y, key);
  }
}

注册场景插件 #

javascript
const config = {
  type: Phaser.AUTO,
  width: 800,
  height: 600,
  plugins: {
    scene: [
      { key: 'MyScenePlugin', plugin: MyScenePlugin, mapping: 'myPlugin' }
    ]
  },
  scene: GameScene
};

使用场景插件 #

javascript
class GameScene extends Phaser.Scene {
  create() {
    this.myPlugin.doSomething();
    
    const sprite = this.myPlugin.addSprite(100, 100, 'player');
  }
}

插件配置 #

全局插件配置 #

javascript
const config = {
  plugins: {
    global: [
      {
        key: 'MyPlugin',
        plugin: MyPluginClass,
        start: true,
        mapping: 'myPlugin',
        data: {
          setting1: 'value1',
          setting2: 'value2'
        }
      }
    ]
  }
};

场景插件配置 #

javascript
const config = {
  plugins: {
    scene: [
      {
        key: 'MyScenePlugin',
        plugin: MyScenePluginClass,
        mapping: 'myScenePlugin',
        systemKey: 'mySystemPlugin',
        sceneKey: 'myScenePlugin'
      }
    ]
  }
};

插件管理 #

安装插件 #

javascript
this.plugins.install('MyPlugin', MyPluginClass, true);

this.plugins.install('MyScenePlugin', MyScenePluginClass, false, 'myPlugin');

启动/停止插件 #

javascript
this.plugins.start('MyPlugin');

this.plugins.stop('MyPlugin');

获取插件 #

javascript
const plugin = this.plugins.get('MyPlugin');

const plugin = this.plugins.getScenePlugin('MyScenePlugin');

移除插件 #

javascript
this.plugins.remove('MyPlugin');

this.plugins.removeScenePlugin('MyScenePlugin');

实用插件示例 #

状态管理插件 #

javascript
class StateManagerPlugin extends Phaser.Plugins.ScenePlugin {
  constructor(scene, pluginManager) {
    super(scene, pluginManager, 'StateManagerPlugin');
    
    this.state = {};
    this.listeners = {};
  }
  
  boot() {
    this.systems.events.on('shutdown', this.shutdown, this);
    this.systems.events.on('destroy', this.destroy, this);
  }
  
  setState(newState) {
    const oldState = { ...this.state };
    this.state = { ...this.state, ...newState };
    
    Object.keys(newState).forEach(key => {
      if (this.listeners[key]) {
        this.listeners[key].forEach(callback => {
          callback(this.state[key], oldState[key]);
        });
      }
    });
    
    return this;
  }
  
  getState(key) {
    return key ? this.state[key] : this.state;
  }
  
  subscribe(key, callback) {
    if (!this.listeners[key]) {
      this.listeners[key] = [];
    }
    this.listeners[key].push(callback);
    
    return () => {
      this.listeners[key] = this.listeners[key].filter(cb => cb !== callback);
    };
  }
  
  shutdown() {
    this.state = {};
    this.listeners = {};
  }
  
  destroy() {
    this.shutdown();
    super.destroy();
  }
}

输入管理插件 #

javascript
class InputManagerPlugin extends Phaser.Plugins.ScenePlugin {
  constructor(scene, pluginManager) {
    super(scene, pluginManager, 'InputManagerPlugin');
    
    this.keys = {};
    this.actions = {};
  }
  
  boot() {
    this.systems.events.on('start', this.start, this);
    this.systems.events.on('shutdown', this.shutdown, this);
  }
  
  start() {
    this.systems.events.on('update', this.update, this);
  }
  
  addKey(name, keyCode) {
    this.keys[name] = this.scene.input.keyboard.addKey(keyCode);
    return this;
  }
  
  addAction(name, callback) {
    this.actions[name] = callback;
    return this;
  }
  
  bindKeyToAction(keyName, actionName) {
    if (this.keys[keyName] && this.actions[actionName]) {
      this.keys[keyName].on('down', this.actions[actionName]);
    }
    return this;
  }
  
  isDown(name) {
    return this.keys[name] ? this.keys[name].isDown : false;
  }
  
  justDown(name) {
    return this.keys[name] ? Phaser.Input.Keyboard.JustDown(this.keys[name]) : false;
  }
  
  justUp(name) {
    return this.keys[name] ? Phaser.Input.Keyboard.JustUp(this.keys[name]) : false;
  }
  
  update() {
  }
  
  shutdown() {
    this.keys = {};
    this.actions = {};
    this.systems.events.off('update', this.update, this);
  }
  
  destroy() {
    this.shutdown();
    super.destroy();
  }
}

粒子效果插件 #

javascript
class ParticleEffectsPlugin extends Phaser.Plugins.ScenePlugin {
  constructor(scene, pluginManager) {
    super(scene, pluginManager, 'ParticleEffectsPlugin');
    
    this.effects = {};
    this.textureKey = 'particle';
  }
  
  boot() {
    this.systems.events.on('shutdown', this.shutdown, this);
  }
  
  setTexture(key) {
    this.textureKey = key;
    return this;
  }
  
  createFire(x, y, config = {}) {
    const emitter = this.scene.add.particles(x, y, this.textureKey, {
      speed: { min: 50, max: 100 },
      angle: { min: -30, max: 30 },
      scale: { start: 1, end: 0 },
      alpha: { start: 1, end: 0 },
      tint: [0xffcc00, 0xff6600, 0xff0000],
      lifespan: 1000,
      frequency: 50,
      blendMode: 'ADD',
      gravityY: -100,
      ...config
    });
    
    return emitter;
  }
  
  createExplosion(x, y, config = {}) {
    const emitter = this.scene.add.particles(x, y, this.textureKey, {
      speed: { min: 200, max: 400 },
      angle: { min: 0, max: 360 },
      scale: { start: 1, end: 0 },
      alpha: { start: 1, end: 0 },
      tint: [0xffcc00, 0xff6600, 0xff0000],
      lifespan: 500,
      frequency: -1,
      blendMode: 'ADD',
      ...config
    });
    
    emitter.explode(config.quantity || 50);
    
    return emitter;
  }
  
  createTrail(target, config = {}) {
    const emitter = this.scene.add.particles(0, 0, this.textureKey, {
      follow: target,
      speed: 0,
      scale: { start: 0.5, end: 0 },
      alpha: { start: 0.5, end: 0 },
      tint: 0x00ffff,
      lifespan: 500,
      frequency: 20,
      blendMode: 'ADD',
      ...config
    });
    
    return emitter;
  }
  
  shutdown() {
    this.effects = {};
  }
  
  destroy() {
    this.shutdown();
    super.destroy();
  }
}

音频管理插件 #

javascript
class AudioManagerPlugin extends Phaser.Plugins.ScenePlugin {
  constructor(scene, pluginManager) {
    super(scene, pluginManager, 'AudioManagerPlugin');
    
    this.bgm = null;
    this.sfxVolume = 1;
    this.bgmVolume = 0.5;
    this.muted = false;
  }
  
  boot() {
    this.systems.events.on('shutdown', this.shutdown, this);
  }
  
  playBGM(key, config = {}) {
    if (this.bgm) {
      this.stopBGM();
    }
    
    this.bgm = this.scene.sound.add(key, {
      volume: this.bgmVolume,
      loop: true,
      ...config
    });
    
    this.bgm.play();
    return this;
  }
  
  stopBGM(fadeOut = 0) {
    if (!this.bgm) return this;
    
    if (fadeOut > 0) {
      this.scene.tweens.add({
        targets: this.bgm,
        volume: 0,
        duration: fadeOut,
        onComplete: () => {
          this.bgm.stop();
          this.bgm = null;
        }
      });
    } else {
      this.bgm.stop();
      this.bgm = null;
    }
    
    return this;
  }
  
  pauseBGM() {
    if (this.bgm) this.bgm.pause();
    return this;
  }
  
  resumeBGM() {
    if (this.bgm) this.bgm.resume();
    return this;
  }
  
  playSFX(key, config = {}) {
    if (this.muted) return null;
    
    return this.scene.sound.play(key, {
      volume: this.sfxVolume,
      ...config
    });
  }
  
  setSFXVolume(volume) {
    this.sfxVolume = volume;
    return this;
  }
  
  setBGMVolume(volume) {
    this.bgmVolume = volume;
    if (this.bgm) this.bgm.setVolume(volume);
    return this;
  }
  
  mute() {
    this.muted = true;
    this.scene.sound.setMute(true);
    return this;
  }
  
  unmute() {
    this.muted = false;
    this.scene.sound.setMute(false);
    return this;
  }
  
  toggleMute() {
    return this.muted ? this.unmute() : this.mute();
  }
  
  shutdown() {
    this.stopBGM();
    this.bgm = null;
  }
  
  destroy() {
    this.shutdown();
    super.destroy();
  }
}

使用第三方插件 #

安装插件 #

bash
npm install phaser3-rex-plugins

使用插件 #

javascript
import RexPlugins from 'phaser3-rex-plugins';

const config = {
  plugins: {
    global: [
      {
        key: 'rexVirtualJoystick',
        plugin: RexPlugins.VirtualJoystick,
        start: true
      }
    ]
  }
};

create() {
  this.joyStick = this.plugins.get('rexVirtualJoystick').add(this, {
    x: 100,
    y: 500,
    radius: 50,
    base: this.add.circle(0, 0, 50, 0x888888),
    thumb: this.add.circle(0, 0, 25, 0xcccccc)
  });
}

下一步 #

现在你已经掌握了插件系统,接下来学习 性能优化,了解如何优化游戏性能!

最后更新:2026-03-29