javascript - ¿Cuál es la mejor manera de compartir variables entre los métodos de clase de Phaser3?
Estoy tratando de encontrar una manera limpia y legible de gestionar variables a través de funciones en una clase de Phaser, pero por diversas razones estoy insatisfecho con las soluciones que he encontrado.
Lo que sé que está disponible:
Variables Globales
No me gusta mucho esta implementación por la posibilidad de que las variables sean accesibles por otros archivos.
var heroes = [];
var play = new Phaser.Class({
Extends: Phaser.Scene,
initialize: function(){
Phaser.Scene.call(this, {key: 'play'});
},
create: function () {
for(var i = 0; i < 5; i++){
heroes.add(new Hero())
}
},
update: function(){
if(!heroes.length){
heroes.add(new Hero())
}
heroes.forEach(function(hero){
if(hero.hp <= 0){
hero.destroy();
}
});
}
});
Clase DataManager (implementada como registro)
Prefiero esto ya que es más controlado, pero para mí DataManager parece estar destinado a configuraciones, no como un medio para procesar/compartir datos entre métodos de clase; además, acceder y actualizar variables se siente muy brusco con un servicio específico para obtener y establecer sus valores.
var play = new Phaser.Class({
Extends: Phaser.Scene,
initialize: function(){
this.registry.set('heroes', []);
Phaser.Scene.call(this, {key: 'play'});
},
create: function () {
var heroes = this.registry.get('heroes');
for(var i = 0; i < 5; i++){
heroes.add(new Hero())
}
this.registry.set('heroes', heroes);
},
update: function(){
var heroes = this.registry.get('heroes');
if(!heroes.length){
heroes.add(new Hero())
}
heroes.forEach(function(hero){
if(hero.hp <= 0){
hero.destroy();
}
});
this.registry.set('heroes', heroes);
}
});
Usando 'esto'
Esto me parece hasta ahora la forma más limpia, ya que esto se refiere al objeto de la clase y es lo suficientemente fácil de actualizar y recuperar valores, PERO en este contexto 'this' se comparte con algunas variables internas específicas de Phaser de las que quiero separar mis variables. Además de usar un espacio de nombres con 'this', ¿hay alguna solución alternativa?
var play = new Phaser.Class({
Extends: Phaser.Scene,
initialize: function(){
this.heroes = [];
Phaser.Scene.call(this, {key: 'play'});
},
create: function () {
for(var i = 0; i < 5; i++){
this.heroes.add(new Hero())
}
},
update: function(){
if(!heroes.length){
this.heroes.add(new Hero())
}
this.heroes.forEach(function(hero){
if(hero.hp <= 0){
hero.destroy();
}
});
}
});
Respuesta #1
Intenté pasar algunos datos globales entre escenas y encontré lo siguiente. Cada escena tiene su propia referencia al registro global. Aquí está la cita de la documentación:
Esta es una instancia de todo el juego del Administrador de Datos, que le permite intercambiar datos entre Escenas a través de un punto universal y compartido.
En la configuración predeterminada, puede acceder a esto desde dentro de una Escena a través de la propiedadthis.registry.
https://photonstorm.github.io/phaser3-docs/Phaser.Data.DataManager.html Aquí está la documentación con la descripción detallada de la clase. Probé esto en un juego reciente: es muy conveniente de usar.
Respuesta #2
La forma más limpia y legible, en mi opinión, sería usar clases adecuadas (y no instancias de Phaser.Class). Siempre puedes extender una clase de Phaser que necesites (como aquí con Phaser.Scene).
TypeScript :
class Play extends Phaser.Scene {
private heroes: Hero[] = [];
private create(): void {
for (let i = 0; i < 5; i++) {
this.heroes.push(new Hero());
}
}
private update(): void {
if (!this.heroes.length) {
this.heroes.push(new Hero());
}
this.heroes.forEach((hero) => {
if (hero.hp <= 0) {
hero.destroy();
}
});
}
public initialize(): void {
Phaser.Scene.call(this, { key: 'play' });
}
}
ES6 (igual, excepto por las declaraciones de tipo y los modificadores de acceso):
class Play extends Phaser.Scene {
heroes = [];
create() {
for (let i = 0; i < 5; i++) {
this.heroes.push(new Hero());
}
}
update() {
if (!this.heroes.length) {
this.heroes.push(new Hero());
}
this.heroes.forEach((hero) => {
if (hero.hp <= 0) {
hero.destroy();
}
});
}
initialize() {
Phaser.Scene.call(this, { key: 'play' });
}
}
Si por alguna razón estás limitado a ES5, entonces tu última sugerencia podría ser tu mejor opción.
