Place status bar / Inventory at every scene

I need the status bar / inventory of items for every scene ?

How do I do this using a class ?

Currently I just repeat the code in every scene in create() ( not very efficient method )

Thanks

        // Black bar 64 pixels for inventory / menu
        let rect = new Phaser.Geom.Rectangle(0, 576, 640, 64);
        let graphics = this.add.graphics({ fillStyle: { color: 0x000000 } });
        graphics.fillRectShape(rect).setScrollFactor(0)

        this.chestSprite = this.add.sprite(20, 595, 'u3').play('chest').setScale(2).setScrollFactor(0)
        this.horseSprite = this.add.sprite(70, 595, 'u3').play('horse').setScale(2).setScrollFactor(0)
        this.iceballSprite = this.add.sprite(120, 595, 'u3').play('iceball').setScale(2).setScrollFactor(0)
        this.fireballSprite = this.add.sprite(170, 595, 'u3').play('fireball').setScale(2).setScrollFactor(0)

        this.chestNum = this.add.text(13, 615, this.inventory.chest, { font: '20px Courier', fill: '#FFFFFF' }).setScrollFactor(0);
        this.horseNum = this.add.text(63, 615, this.inventory.horse, { font: '20px Courier', fill: '#FFFFFF' }).setScrollFactor(0);
        this.iceballNum = this.add.text(113, 615, this.inventory.iceball, { font: '20px Courier', fill: '#FFFFFF' }).setScrollFactor(0);
        this.fireballNum = this.add.text(163, 615, this.inventory.fireball, { font: '20px Courier', fill: '#FFFFFF' }).setScrollFactor(0);

That depends on your setup. Are you using any kind of bundler like webpack for example?
Then it’s very easy to either create a base class and extend every scene, in which you need the inventory.

// BaseScene.js
export default class BaseScene extends Phaser.Scene {
    constructor (mapId) {
        super({ key: mapId })
    }

    create () {
        // YOUR INVENTORY CODE
    }
}

// AnotherScene.js
import BaseScene from './BaseScene.js'

class AnotherScene extends BaseScene {
    constructor () {
        super('AnotherScene')
    }

    create () {
        // Calls the BaseScene.create() function.
        // If you just need the parent function here, you can even remove it.
        super.create()
    }
}

Or if you don’t want to create a BaseClass, you can also put it in a function in an extra file.

// inventory.js
export const createInventory = () => {
    // YOUR INVENTORY CODE
}

// AnotherScene.js
import { createInventory } from './inventory.js'

class AnotherScene extends Phaser.Scene {
    ....

    create () {
        createInventory()
    }

    ....
}
1 Like

Thanks for both suggestions …

I m just on index.html script tags ( no webpacks ), how do I make my function global to Phaser3 and access this ?

Rather than extending scenes into subclasses and using a shared component in each scene (though that would totally work), another option would be to make your inventory bar its own scene. In Phaser 3, scenes can run in parallel, on screen at the same time, and you can control which one shows on top with methods like SceneManager’s bringToTop(key). Information can be passed between scenes, so you can do something in a gameplay scene, and send info to your inventory bar scene, and vice versa.

I’d say that’s kind of the way Phaser 3 expects you to do it, but there are always 100 ways to do things, and if it works for you, it works for you! Check out some tutorials and examples on the different things scenes can do, especially loading multiple scenes at once, and it might start to make more sense.

1 Like

Thank you all for your replies…

I kinda like the idea of running it as a parallel scene , in phaser style…

Updates, after reading up about scenes & events, I “figured” out to use launch instead of scene.start to run the scenes in parallel …

// Launch showInventory scene
this.scene.launch('showInventory', { player: player,inventory : this.inventory })

I also wrote a function to send event to that scene to update the quantity in the inventory…

updateDisplay() {
        // Emit events showInventory
        console.log('Emit event', this.inventory)
        this.invEvent = (event, data)=> this.scene.get('showInventory').events.emit( event, data);
        this.invEvent( "inventory", this.inventory);
    }

In showInventory scene, to receive the event and use text.setText() to updates the numbers

// Recv an event
this.events.on('inventory', this.updateInventory, this)

updateInventory codes below :

  updateInventory(data) {
        console.log('Received event inventory', data)
        this.inventory = {}
        this.inventory = data
        this.chestNum.setText( this.inventory.chest );
        this.horseNum.setText( this.inventory.horse );
        this.iceballNum.setText( this.inventory.iceball );
        this.fireballNum.setText( this.inventory.fireball ); 

    }
1 Like