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>