I'm creating four buttons, using the game engine Phaser 3. I try to give each button a custom size based on the screen size (so it always fits nice in the screen no matter what screen size). At first it creates the buttons in the correct size, but once you hover over them, the highlighted method brings them back to the original size of the image. What is wrong with my code?
displayAnswerButtons(answers) {
const buttonYStart = window.innerHeight / 6 * 4;
const buttonSpacingY = window.innerHeight / 6 / 10;
const buttonWidth = this.screenWidth * .4;
const buttonHeight = window.innerHeight * .12;
if (buttons.length > 0) {
buttons.forEach(button => { button.destroy(); });
}
for (let i = 0; i < answers.length; i++) {
let row = Math.floor(i / 2);
let col = i % 2;
let x = (col == 0) ? this.screenWidth / 4 : (this.screenWidth / 4) * 3;
let y = (row == 0) ? buttonYStart : buttonYStart + buttonHeight + buttonSpacingY;
this.createAnswerButton(x, y, buttonWidth, buttonHeight, this.buttonImages[i].key, answers[i], row, col);
}
this.highlightButton(this.buttons[this.selectedButtonIndex.row][this.selectedButtonIndex.col]);
}
createAnswerButton(x, y, buttonWidth, buttonHeight, imageKey, answer, row, col) {
// Create button container
let buttonContainer = this.add.container(x, y);
// Button background image
let buttonImg = this.add.image(0, 0, imageKey);
this.xScale = buttonWidth / buttonImg.width;
this.yScale = buttonHeight / buttonImg.height;
buttonImg.setScale(this.xScale, this.yScale);
console.log("SCALE: ", buttonWidth / buttonImg.width, buttonHeight / buttonImg.height);
console.log("Img size: ", buttonImg.width, buttonImg.height);
console.log("Display size: ", buttonImg.displayWidth, buttonImg.displayHeight);
// Display answer text centered inside the button
let text = this.add.text(0, 0, answer.text, {
fontSize: `${Math.floor(buttonHeight * 0.3)}px`, // Scale text based on button height
fill: '#000000',
fontWeight: 'bold',
fontFamily: 'Arial'
}).setOrigin(0.5, 0.5);
// Add elements to container
buttonContainer.add([buttonImg, text]);
// Calculate the size of the container based on its children (button image and text)
const bounds = buttonContainer.getBounds(); // Get bounds of the container
buttonContainer.setSize(bounds.width, bounds.height); // Set the size of the container based on the bounds
console.log("BOUNDS CONTAINER: ", bounds.width, bounds.height);
// Store button in buttons array
if (!this.buttons[row]) this.buttons[row] = [];
this.buttons[row][col] = {
container: buttonContainer,
correct: answer.correct
};
}
highlightButton(buttonObject) {
let buttonImage = buttonObject.container.list[0];
let buttonText = buttonObject.container.list[1];
console.log("Image: ", buttonImage);
console.log("Text: ", buttonText);
this.tweens.add({
targets: buttonImage,
scale: 1.1,
duration: 200,
ease: 'Power5'
});
this.highlightText(buttonText);
}
clearHighlight(buttonObject) {
let buttonImage = buttonObject.container.list[0];
let buttonText = buttonObject.container.list[1];
this.tweens.add({
targets: buttonImage,
scale: 1,
duration: 200,
ease: 'Power5'
});
this.clearHighlightText(buttonText);
}
The issue it that you are setting a scale to the buttons
buttonImg.setScale(this.xScale, this.yScale);
but in the tweans of clear and *highlight *functions your are setting it back to some fixed values:
...
this.tweens.add({
targets: buttonImage,
scale: 1, // <-- Problem Code
duration: 200,
ease: 'Power5'
});
...
The 1
would have to be replaced with the value you calculate by creating the button (also the 1.1
from the highlight might need tweaking).
Change your code to something like this (assuming this.xScale, this.yScale
are the same values from the button creation):
...
this.tweens.add({
targets: buttonImage,
scaleX: this.xScale,
scaleY: this.yScale,
duration: 200,
ease: 'Power5'
});
...