Home > Net >  Phaser 3: Text centered within Rectangle
Phaser 3: Text centered within Rectangle

Time:02-15

I am trying to make a little menu bar, however I am struggling to place the text of the buttons centered within the rectangles of the buttons. Currently I am simply giving the text the same x and y settings as my rectangles, however that doesn't place them centered. Are there options to center text within a rectangle?

function create()
{
   // Menu Bar
   gameState.menu.height = 80;
   gameState.menu.width = this.gameWidth;
   gameState.menu.x = gameState.gameWidth/2;
   gameState.menu.y = gameState.gameHeight - (gameState.menu.height - gameState.menu.height/2);
   gameState.menu.options = [
       "Feed", "Bathe", "Play"
   ];
   gameState.menu.items = [];

   gameState.menu.bar = this.add.rectangle(gameState.menu.x, gameState.menu.y, gameState.gameWidth, gameState.menu.height, '0x123456');
   gameState.menu.itemSize = (gameState.gameHeight/100*90) / gameState.menu.options.length;

   // Menu Items
   gameState.menu.itemSpace = (gameState.gameHeight - (gameState.menu.itemSize * gameState.menu.options.length)) / (gameState.menu.options.length   1);

   x = gameState.menu.itemSpace   (gameState.menu.itemSize / 2);
   index = 0;
   for (o of gameState.menu.options)
   {
       gameState.menu.items.push(this.add.rectangle(x, gameState.gameHeight - (gameState.menu.height/2), gameState.menu.itemSize, gameState.menu.height - 20, '0x654321'));
       o = this.add.text(x, gameState.gameHeight - (gameState.menu.height/2), o, gameState.textStyle);
    
       index  ;
       x  = gameState.menu.itemSize   gameState.menu.itemSpace;
   };

}

CodePudding user response:

As mentioned in the comment, a fast solution is to use Phaser.Display.Align.In.Center, for details please refere to it (https://stackoverflow.com/a/70956429/1679286), or the documentaion(also linked in the initial answer).

I'm not sure why the error mentioned in the comment apears. I converted your code to use the Phaser.Display.Align.In.Center function, this version it should work (fix the problem).

Demo-Code:
(had to fake some code)

let Scene = {
      create(){
       // Menu Bar  
       // Faked Start data
       let gameState = {menu:{}};
       gameState.gameWidth = 400;
       gameState.gameHeight = 200;
       // Faked End data
       
       gameState.menu.height = 80;
       gameState.menu.width = this.gameWidth;
       gameState.menu.x = gameState.gameWidth/2;
       gameState.menu.y = gameState.gameHeight - (gameState.menu.height - gameState.menu.height/2);
       gameState.menu.options = [
           "Feed", "Bathe", "Play"
       ];
       gameState.menu.items = [];

       gameState.menu.bar = this.add.rectangle(gameState.menu.x, gameState.menu.y, gameState.gameWidth, gameState.menu.height, '0x123456');
       gameState.menu.itemSize = (gameState.gameHeight/100*90) / gameState.menu.options.length;

       // Menu Items
       gameState.menu.itemSpace = (gameState.gameHeight - (gameState.menu.itemSize * gameState.menu.options.length)) / (gameState.menu.options.length   1);

       let x = gameState.menu.itemSpace   (gameState.menu.itemSize / 2);

       for (let idx = 0; idx < gameState.menu.options.length; idx  )
       {
           let optionText = gameState.menu.options[idx];
           let button  = this.add.rectangle(x, gameState.gameHeight - (gameState.menu.height/2), gameState.menu.itemSize, gameState.menu.height - 20, '0x654321');
           let text  = this.add.text(0, 0, optionText);
           gameState.menu.items.push(button);
           Phaser.Display.Align.In.Center(text, button);
           x  = gameState.menu.itemSize   gameState.menu.itemSpace;
       };

      }

    }
    
    const config = {
      type: Phaser.AUTO,
      width:400,
      height:200,
      scene: [Scene],
      physics: {
          default: 'arcade',
          arcade: {
          debug: false,
          gravity: { y: 400 }
          }
      }
    }


   const game = new Phaser.Game(config)
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/phaser.js"></script>

p.s.: I would try not to use too many global variables, keep them local or may be use properties. Will make your live easier in the long run.

p.p.s.: there is a free plugin that can be used to create UI's in phaser: https://rexrainbow.github.io/phaser3-rex-notes/docs/site/ui-menu/

It is abit tricky (and needs "some" boilerplate-code), but this plugin has many feature.

here how one could do a menu with the tab control:

class Demo extends Phaser.Scene {
    constructor() {
        super({
            key: 'examples'
        })
    }

    preload() { 
        this.load.scenePlugin({
            key: 'rexuiplugin',
            url: 'https://raw.githubusercontent.com/rexrainbow/phaser3-rex-notes/master/dist/rexuiplugin.min.js',
            sceneKey: 'rexUI'
        });      
    }

    create() {
      
        let buttonName = ['Button 1', 'Button 2', 'Button 3'];
        let tabs = this.rexUI.add.tabs({
                x: 200,
                y: 100,

                background: this.rexUI.add.roundRectangle(0, 0, 10, 10, 0, 0x333333),
                panel: this.rexUI.add.roundRectangle(0, 0, 400, 150, 20, 0x333333),

                bottomButtons: buttonName.map(name => this.createButton(name)),

                space: {
                    left: 20,
                    right: 20,
                    top: 20,
                    bottom: 20,

                    leftButtonsOffset: 20,
                    rightButtonsOffset: 20,
                    topButtonsOffset: 20,
                    bottomButtonsOffset: 20,

                    leftButton: 10,
                    rightButton: 10,
                    topButton: 10,
                    bottomButton: 10
                }
            })
            .layout()
    }
  
  createButton(text){  
    return this.rexUI.add.label({
      background: this.rexUI.add.roundRectangle(0, 0, 100, 50, {
        bl: 0,
        br: 0
      }, 0x654321),
      text: this.add.text(0, 0, text, {
        fontSize: '12pt'
      }),
      space: {
        left: 10,
        right: 10,
        top:10,
        bottom:10
      }
    });
  }

}


const config = {
    type: Phaser.AUTO,
    width: 400,
    height: 200,
    scene: Demo
};

const game = new Phaser.Game(config);
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/phaser.js"></script>

  • Related