scalingphaser-framework

Tweens method converts my buttons back to their original size an and not the custom one I gave them


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);
    }

Solution

  • 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'
        });
        ...