Phaser3类方法间共享变量的最优实现方案是什么?
嘿,我太懂你这种不想用全局变量的纠结了——全局变量不仅容易造成命名冲突,还会让代码的可维护性大打折扣,谁都不想 debug 半天发现是别的文件改了自己的变量对吧?针对Phaser类里跨函数共享变量的问题,我给你几个更靠谱的方案:
1. 使用类的实例属性(最推荐)
这是最贴合面向对象设计的方案,把变量绑定到场景实例上,只有当前场景的方法能访问,完全避免全局污染,而且写法简洁直观。
var play = new Phaser.Class({ Extends: Phaser.Scene, initialize: function PlayScene() { Phaser.Scene.call(this, { key: 'play' }); // 在初始化时定义实例级变量,所有类方法都能访问 this.heroes = []; }, create: function () { // 直接通过this操作变量 for(var i = 0; i < 5; i++) { this.heroes.push(this.add.sprite(100*i, 200, 'hero')); } }, update: function() { // 在update里也能轻松访问到heroes this.heroes.forEach(hero => { hero.x += 1; }); } });
这个方案的优势在于变量完全封装在场景实例内部,除非你主动把实例暴露给其他文件,否则外部根本碰不到它,完美解决了你担心的全局访问问题。
2. 利用Phaser的Scene Registry
Phaser自带的registry是专门用来管理场景数据的工具,它既可以在当前场景内部共享变量,也支持跨场景传递数据。如果你的变量需要在场景重启或者切换时保留,这个方案会很方便。
var play = new Phaser.Class({ Extends: Phaser.Scene, initialize: function PlayScene() { Phaser.Scene.call(this, { key: 'play' }); }, create: function () { // 初始化registry中的变量 this.registry.set('heroes', []); for(var i = 0; i < 5; i++) { const hero = this.add.sprite(100*i, 200, 'hero'); this.registry.get('heroes').push(hero); } }, update: function() { // 取出变量进行操作 const heroes = this.registry.get('heroes'); heroes.forEach(hero => { hero.x += 1; }); } });
不过如果只是当前场景内部使用,实例属性会更直接,registry更适合跨场景的数据共享场景。
3. 模块级私有变量(ES6模块场景下)
如果你的项目已经用上了ES6模块,可以把变量放在模块内部,只导出场景类,这样变量就完全是模块私有的,外部文件根本访问不到。
// playScene.js // 模块内部的私有变量,只有当前模块能访问 const heroes = []; export default class PlayScene extends Phaser.Scene { constructor() { super({ key: 'play' }); } create() { for(var i = 0; i < 5; i++) { heroes.push(this.add.sprite(100*i, 200, 'hero')); } } update() { heroes.forEach(hero => { hero.x += 1; }); } }
注意:这种方式下变量是模块级的,如果你的场景会被实例化多次,所有实例会共享同一个heroes数组,所以只适合单实例的场景。
内容的提问来源于stack exchange,提问作者camjocotem
相关产品推荐
相关产品推荐

