Vyhledávání na webu

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í vlastnosti this.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.