Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial rectangle positioning varies depending on width #6777

Open
codeimpossible opened this issue Mar 28, 2024 · 3 comments
Open

Initial rectangle positioning varies depending on width #6777

codeimpossible opened this issue Mar 28, 2024 · 3 comments

Comments

@codeimpossible
Copy link

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

@photonstorm
Copy link
Collaborator

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

@UnaiNeuronUp
Copy link

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

@photonstorm
Copy link
Collaborator

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants