MoonTown

phaser.World position is in Camera space?

Recommended Posts

Hi Folks!
In the game I'm working on, I find I am unable to spawn Sprites off screen.

It looks like when I scroll foward in the game, the game.world.position.x is updated to be the negative of camera.x.

This causes my sprites intended position to become strongly negative:

 

instantiating a robodillo at (10, 4)

Phaser.Sprite.prototype.preUpdate  ...  this.world.setTo(this.parent.position.x + this.position.x)// this.position.x == 320 (10*32?)// this.parent.position.x == -1545// => this.world.x = -1225

Then, later in Phaser.Physics.Arcade.Body.checkWorldBounds, the body's position is compared against physics.arcade.bounds.x

This, atlast, seems to force sprite position to '0'. moving it 1200 pixels to the right, on to the screen.

Phaser.Physics.Arcade.Body.checkWorldBounds  ...
 if (this.position.x < this.game.physics.arcade.bounds.x ...     this.position.x = this.game.physics.arcade.bounds.x; // this.position.x == -1227.2222222222222// this.game.physics.arcade.bounds.x == 0

 

So where is Phaser.World position updated?

 

When I intent to specify world coordinates of a sprite, am I really intending to specify them in Phaser.state coordinates?

 

 Its weird to me that World.position is anything other than (0,0). This seems super confused.

 

Thanks in Advance!
Alex Mouton

Share this post


Link to post
Share on other sites

You shouldn't really set Sprite.world directly (there are times it makes sense, but they are super rare).

 

Sprite.x/y are the Sprite coordinates within world space, relative to its parent, not relative to 0,0 (unless of course its parent is at 0,0)

 

Sprite.world.x/y is the world coordinates, taking scaling and display hierarchy into account.

 

If you start adjusting Sprite.world or Sprite.position directly then you bypass the extremely important getters and setters that sync up all the coordinates between the Sprite and its physics body.

 

Assuming you've resized your game world to be 2000 pixels wide (via game.world.resize or setBounds), then sprite.x = 1000 would appear in the middle of that world - providing it doesn't have a parent located elsewhere.

Share this post


Link to post
Share on other sites

Hi Rich

In this case I'm not modifying my Sprites position.  

To clarify, My class Robodillo extends Sprite, and it's constructor takes an initial position in terms of Tiles.

 

 

The changes that I've outlined above are all in Phaser code:

Phaser.Sprite.prototype.preUpdate

Phaser.Physics.Arcade.Body.checkWorldBounds

 

 

This robodillo instance is a direct child of World, so when sprite.parent.x == -1545 I wonder what that means.

Why is Phaser.World have a translation stored in its position attribute.

Why is World.position.x not 0?

It seems that World coordinates are not actually in World space, but Phaser.State space.

Since it does seem to be changing... do you know where Phaser.World.position is set?

 

Thanks

Alex Mouton

Share this post


Link to post
Share on other sites

What I'm wondering is if it's intentional that a Sprite created during gameplay (with the camera set to FOLLOW_PLATFORMER) would have its coordinates clamped to the camera's current view?

 

I've also noticed that if you try to kill and reset a sprite, you have to reset the sprite to coordinates that are within the camera's view. If you specify coordinates that are outside those bounds, the sprite is moved to the nearest on-screen location.

 

 

If these are both the intended behavior, I'm wondering what folks do when they want something to spawn (or respawn) offscreen. Or if these aren't the intended behavior, is there something I may have set incorrectly that would cause this to happen?

Share this post


Link to post
Share on other sites

Hi Rich

In this case I'm not modifying my Sprites position.  

To clarify, My class Robodillo extends Sprite, and it's constructor takes an initial position in terms of Tiles.

 

 

The changes that I've outlined above are all in Phaser code:

Phaser.Sprite.prototype.preUpdate

Phaser.Physics.Arcade.Body.checkWorldBounds

 

 

This robodillo instance is a direct child of World, so when sprite.parent.x == -1545 I wonder what that means.

Why is Phaser.World have a translation stored in its position attribute.

Why is World.position.x not 0?

It seems that World coordinates are not actually in World space, but Phaser.State space.

Since it does seem to be changing... do you know where Phaser.World.position is set?

 

 

The way the camera works is to move the World Group, which is itself a display object. This is why the world.x values change. If you scroll 1000 pixels to the right then world.x will be -1000. So to the left it'll be +1000.

 

However this doesn't make any difference to children because they are positioned based on the Worlds coordinate space, not its location.

 

Sprite.x = 1000 will always be 1000, no matter what World.x is, because the value is relative to the 0,0 point of the World (which by default is the top-left, but is actually the center of the World)

 

The Sprite position would only become strongly negative if you set it to match the World.x coordinate, but that isn't something you'd ever want to do, because you're not working in the same coordinate space then.

 

For example:

 

Assume the World is 2000x600 with 0,0 being top-left.

Sprite.x = 1000

 

Now move the Camera to 960 (so camera.x = 960)

 

World.x will be -960, but Sprite.x, Sprite.position.x and Sprite.world.x will still all be 1000. The only value that is different is Sprite.worldTransform.tx (which would be 40 in this case).

 

If you set Sprite.x = World.x then it will become whatever World.x is, which could be massively negative or positive. So if the World is 2000x600, but Camera is 960, then Sprite.x = World.x would put Sprite.x at -960, which is well outside the World bounds. If the Sprite is set to remain within the World bounds it will be pushed back in again.

 

World also doesn't have to have 0,0 as the top-left. It's actually the center of the display object. If you set World bounds to be -1000, -1000, 2000, 2000 then you've got a 2000x2000 sized world centered around 0,0. If a Sprite is now put at -500,-500 it will be placed in the top left area of the World.

Share this post


Link to post
Share on other sites

To try and clarify further:

 

Say you add a Group into your world and set Group.x to 500.

 

Now add a Sprite to the Group and set Sprite.x to 100.

 

The Sprite will visually be rendering at 600px, but Sprite.x and Sprite.position.x will still be 100, because that is how much it is offset from its parent.

 

Sprite.world.x however will be 600: the 500 of its parent + 100 of itself.

 

No matter where in the world the camera currently is these values won't change unless you explicitly change them.

Share this post


Link to post
Share on other sites

It depends if "offscreen" is actually "outside the game world". By default the game world and the game size are the same, so if you haven't adjusted it then yes, collideWorldBounds would definitely push a sprite back into the 'screen' again. If you need a buffer area around your screen you could always resize the game world to be the screen size + however much buffer space you need around the edges. Then you could spawn the sprites within world, but still off-screen.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Recently Browsing   0 members

    No registered users viewing this page.