phaser icon indicating copy to clipboard operation
phaser copied to clipboard

Initial rectangle positioning varies depending on width

Open codeimpossible opened this issue 4 months ago • 3 comments

Version

  • Phaser Version: 3.80.1
  • Operating system: Windows
  • Browser:

Description

This could definitely be a documentation issue, it's not clear if the x and y values passed into scene.add.rectangle() are intended to be the world-space of the center of the rectangle, or the world-space of the top-left of the rectangle. If they are meant to be the top-left then there is a bug with how the rectangle placement is calculated as it changes depending on the rectangle size at creation.

What I did

I created two rectangles at the same x,y position. The first has a fixed size and the second starts with a smaller width and increases over time.

What happened

The first rectangle (fixed size) is rendered with its center point seemingly where the top-left of the second rectangle is in world-space. The second rectangle (dynamic size) stays in place, but expands to the right over time (as I expected).

What did I expect to happen

I expected that the first rectangle would have the same behavior as the second, treating the x,y position as the location of the top-left corner instead of the center point.

Example Test Code

class Example extends Phaser.Scene
{
    timedEvent;
    progressBar;
    progressBarWrapper;
    progressBarSize;

    init() {
        const centerX = 400, centerY = 300;
        this.progressBarSize = { width: 800 / 2, height: 32 };
        const progressBarPos = { x: centerX - this.progressBarSize.width / 2, y: centerY - this.progressBarSize.height / 2 };
        const progressBarStartWidth = 4;

        this.progressBarWrapper = this.add.rectangle(progressBarPos.x - 1, progressBarPos.y - 1, this.progressBarSize.width + 2, this.progressBarSize.height + 2).setStrokeStyle(1, 0xffffff);
        this.progressBarWrapper.width = this.progressBarSize.width;
        this.progressBar = this.add.rectangle(progressBarPos.x, progressBarPos.y, progressBarStartWidth, this.progressBarSize.height, 0xffffff);
        this.timedEvent = this.time.delayedCall(3000, this.finishLoading, [], this);
    }

    updateProgress(progress) {
        this.progressBar.width = this.progressBarSize.width * progress;
    }

    update ()
    {
        this.updateProgress(this.timedEvent.getProgress());
    }

    finishLoading() {

    }
}

const config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    backgroundColor: '#2d2d2d',
    parent: 'phaser-example',
    scene: Example
};

const game = new Phaser.Game(config);

Image of the above code running on the Phaser Labs site: image

codeimpossible avatar Mar 28 '24 12:03 codeimpossible

x/y coordinates for all Game Objects is the center by default. This can be changed via the setOrigin() method.

photonstorm avatar Mar 28 '24 13:03 photonstorm

Changing width property is ignoring the origin of the rectangle.


class MainScene extends Phaser.Scene {
    timedEvent;
    progressBar;

    constructor() {
        super({ key: "MainScene" });
    }

    create() {
        this.rectWidth = 200;
        this.add.rectangle(200, 200, this.rectWidth, 60).setStrokeStyle(1, 0xffffff);
        

        // Use one of these lines to see different behaviors
        this.progressBar = this.add.rectangle(200, 200, 0, 60, 0xffffff);
        // this.progressBar = this.add.rectangle(200, 200, this.rectWidth, 60, 0xffffff);


        this.timedEvent = this.time.delayedCall(3000);
    }

    update() {
        this.progressBar.width = this.rectWidth * this.timedEvent.getProgress();
    }

}

const game = new Phaser.Game({
    type: Phaser.AUTO,
    width: 800,
    height: 800,
    backgroundColor: '#111111',
    scale: {
        mode: Phaser.Scale.FIT,
        autoCenter: Phaser.Scale.CENTER_BOTH
    },
    scene: [ MainScene ]
})

UnaiNeuronUp avatar Apr 30 '24 09:04 UnaiNeuronUp

If you want to change the intrinsic width (as above) then you can use the width property like this, and it will extend out from the origin to the right. If you want to change how it renders, factoring in the origin, use displayWidth instead.

photonstorm avatar Apr 30 '24 10:04 photonstorm