On screen buttons, a better way of doing this?

create(){
        // assigning player object to a physic
        this.player = new Player({scene:this,x:1000,y:600,texture:'character',frame:'male_1'});
        // printing sprite onto screen
        this.player.setScale(3);
        this.btnUp = this.add.existing(new GameButton(this,1700, 800, 'buttons', 'btnup'));
        this.btnLeft = this.add.existing(new GameButton(this,1604, 896, 'buttons', 'btnleft'));
        this.btnDown = this.add.existing(new GameButton(this,1700, 992, 'buttons', 'btndown'));
        this.btnRight = this.add.existing(new GameButton(this,1796, 896, 'buttons', 'btnright'));
        this.btnInteract = this.add.existing(new GameButton(this,1700, 896, 'buttons', 'btninteract'));
        this.btnUp.onPressed=()=> {
            this.player.setVelocityY(-5);
            this.player.anims.play('walking_back',true);
        }
        this.btnUp.onReleased=()=> {
            this.player.anims.play('idle_back',true);
        }
        this.btnLeft.onPressed =()=> {
            this.player.setVelocityX(-5);
            this.player.anims.play('walking_left',true);
        }
        this.btnLeft.onReleased=()=> {
            this.player.anims.play('idle_left',true);
        }
        this.btnRight.onPressed =()=> {
            this.player.setVelocityX(5);
            this.player.anims.play('walking_right',true);
        }
        this.btnRight.onReleased=()=> {
            this.player.anims.play('idle_right',true);
        }
        this.btnDown.onPressed =()=> {
            this.player.setVelocityY(5);
            this.player.anims.play('walking_forward',true);
        }
        this.btnDown.onReleased=()=> {
            this.player.anims.play('idle_forward',true);
        }


    }
    update() {
        this.player.update();
        this.btnUp.update();
        this.btnLeft.update();
        this.btnRight.update();
        this.btnDown.update();
    }

This code is creating 5 on-screen buttons that the user is able to click to move the character. All this code is placed in the Main Scene script, should I create a custom class to group all these buttons together or how should I go about doing this?

What I usually do and see people doing, is having a separate Scene, just for UI. It’s better to have them separately, because if in any case you need to zoom your Main Scene, all UI will be zoomed too, therefore being too small or too big. If you have a separate Scene for UI you won’t have to worry about Camera positioning while making the camera follow your Sprite.

Whenever you can, split things up.

I have this Demo, where you will be able to see what I mean. There I think I’m using a 2.5 Zoom.

https://skyalpha.github.io/luminus-rpg.github.io/

You can check the code here if you want to have the reference.

2 Likes

Oh wow! Thank you very much, I am relatively new to programming and game dev, the only other engine I have worked with was Unity and they had a UI feature for their scenes, I did not know you could layer scenes!

Edit: sorry to bother you but I have one more question about the class creation, why is it that I sometimes see people passing parameters for the class into the constructor() function while you have done it through an init() function is there any difference?
eg.

 constructor(scene, x, y, texture, frame = null)
    {
        super(scene, x, y, texture, frame);

vs

constructor() {
        super({
            key: 'HUDScene',
        });

        this.player = null
    }

    init(args) {
        this.player = args.player;

Adding parameters to the constructor apply to the scene class when an instance of that scene is created - this is pure ES6 javascript.

The “init” function is a reserved method name on the scene class. Much like create and update, defining this method in your class that extends the base “scene” class will overwrite that method. The scene init method gets called before preload and create and receives a data argument from scenePlugin.add() or scenePlugin.start().
https://photonstorm.github.io/phaser3-docs/Phaser.Types.Scenes.html#.SceneInitCallback
In most cases, they kinda functionally do the same thing… bet if there were ever a case where you needed to CREATE an instance of a scene, then sometime later on add the scene to your game via the scenePlugin (maybe the scene was “stopped” and removed from the scene list, and needs to be added again), init is how you’d receive data to the newly added/started scene (since the constructor was already called sometime in the past, and the scene instance, though unused at the moment by Phaser, technically could still exist in memory)

1 Like