phaserjs / phaser-ce

Phaser CE is a fun, free and fast 2D game framework for making HTML5 games for desktop and mobile web browsers, supporting Canvas and WebGL rendering.
http://phaser.io
MIT License
1.35k stars 491 forks source link

arcade bodies do not scale with camera #315

Open fyyyyy opened 7 years ago

fyyyyy commented 7 years ago

This Issue is about

See also a potential fix. https://github.com/RolandMQuiros/phaser/commit/f732cc1129c28f1cd821e28259f942f34a11c1a6

samme commented 7 years ago

Yes, it's always worked this way. https://codepen.io/samme/pen/OWyPqq

Maybe we can scale the body by worldScale instead.

fyyyyy commented 7 years ago

Is it possible to attache listeners to the camera ? So that entities can subscribe to a camera onScale event and scale their bodies accordingly. This would make it easier to update all bodies in the world.

n/m i figured this out i believe

  // init() ...
   game.camera.scale.onChange = new Phaser.Signal();

 // whenever you change camera scale, dispatch the event
    this.game.camera.scale.onChange.dispatch();

 // in your sprites, listen to the event
    this.game.camera.scale.onChange.add(this.updateBody.bind(this));

// update body
updateBody() {
  this.body.setSize(width * this.game.camera.scale.x, ...
}
samme commented 7 years ago

That looks good. You can also pass params like

this.game.camera.scale.onChange.dispatch(this.game.camera.scale);
// …
updateBody(cameraScale) {
  this.body.setSize(/* … */);
}
fyyyyy commented 7 years ago

ok thanks, here is an example in case anyone is curious. https://codepen.io/anon/pen/ayqMLP?editors=0010

samme commented 7 years ago

I made a branch for this, substituting sprite.worldScale for sprite.scale. The body size was correct but the offset was not, so I guess I've missed something.

fyyyyy commented 7 years ago

I guess all my sprites had anchor 0.5, thats why there wasnt any offset issues when scaling

samme commented 7 years ago

I think it's complicated because with worldScale the scale origin is the the top-left of the group (usually [0, 0]), whereas with scale it's the sprite's anchor.

fyyyyy commented 7 years ago

maybe it should work like the fixedToCamera: true property as in scaleWithCamera: true or scaleWithWorld: true Then users can set it individually for groups or sprites, by default its false to not break existing code.

samme commented 7 years ago

I think the formula in https://github.com/photonstorm/phaser-ce/blob/v2.8.5/src/physics/arcade/Body.js#L618 needs to be changed somehow if worldScale is substituted there.

hexus commented 7 years ago

The real fix here is not to scale physics at all, but instead detach camera scaling from physics entirely.

https://github.com/hexus/phaser-ce/compare/master...camera-transform

This is a branch I've been working on, but I've only been hesitant to make a PR because it's a big change and will need some testing across all examples.

samme commented 7 years ago

Well there's always https://codepen.io/samme/full/ZLbGzB/ 😸

hexus commented 7 years ago

Looks great, but changes the resolution of the canvas! Ouch!

samme commented 7 years ago

https://codepen.io/samme/pen/vegxZz

hexus commented 7 years ago

Also looks pretty nice, though it's using CSS, and the world is cropped if you zoom out further than 1x.

I still think the best solution is to decouple the camera from the physics, as I've implemented. :)

By the way, are you on the Phaser Slack @samme?

samme commented 6 years ago

body.syncBounds may help with this.