javascript - Jaký je nejlepší způsob, jak sdílet proměnné mezi metodami třídy v Phaser3?
Snažím se najít čistý, přehledný způsob, jak spravovat proměnné mezi funkcemi v třídě Phaser, ale z různých důvodů nejsem spokojený s řešeními, která jsem našel.
Co je mi známo, je dostupné:
Globální proměnné
Nejsem příliš nadšený z této implementace kvůli možnosti, že proměnné budou přístupné z jiných souborů.
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();
}
});
}
});
Třída DataManager (implementována jako registr)
Dávám přednost tomuto, protože je to více kontrolované, ale pro mě DataManager působí, jako by byl určen pro konfigurace, ne jako prostředek k zpracování/sdílení dat mezi metodami třídy; také přístup a aktualizace proměnných se zdá být velmi těžkopádné s konkrétní službou pro získávání a nastavení jejích hodnot.
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);
}
});
Použití 'this'
Toto mi zatím připadá jako nejčistší způsob, protože se to odkazuje na objekt třídy a je dostatečně snadné aktualizovat a získávat hodnoty, ALE v tomto kontextu je 'this' sdíleno s některými interními proměnnými specifickými pro Phaser, od kterých chci své proměnné oddělit. Kromě používání jmenného prostoru s 'this', existují nějaká alternativní řešení?
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();
}
});
}
});
Odpověď č. 1
Snažil jsem se předat některá globální data mezi scénami a zjistil následující. Každá scéna má vlastní odkaz na globální registr. Zde je citát z dokumentace:
Toto je herně celoplošná instance Správce dat, která vám umožňuje výměnu dat mezi scénami prostřednictvím univerzálního a sdíleného bodu.
V základním nastavení k tomu můžete ve scéně přistupovat pomocí vlastnostithis.registry.
https://photonstorm.github.io/phaser3-docs/Phaser.Data.DataManager.html Zde je dokumentace s podrobným popisem třídy. Zkoušel jsem to v nedávné hře - je to při použití velmi pohodlné.
Odpověď č. 2
Nejčistší a nejsrozumitelnější způsob podle mého názoru by bylo používat správné třídy (a ne instance Phaser.Class). Vždy si můžete rozšířit třídu Phaser, kterou potřebujete (jako zde s 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 (stejné, kromě deklarací typů a přístupových modifikátorů):
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' });
}
}
Pokud jste z nějakého důvodu uvázáni u ES5, pak může být vaše poslední návrh tou nejlepší volbou.
