This appears to do exactly what I want:
- custom Plane class extends
Container
; its constructor creates all the little sub-pieces: physics sprites, text, shapes, etc. - when you extend
Container
, Phaser seems to require that you also define apreUpdate(time, delta)
method on your subclass; in that method, I explicitly update the positions of each of the sub-pieces by re-assigning into their x & y coords
Like so:
export default class Plane extends Phaser.GameObjects.Container {
constructor( scene, x, y, name, size ) {
super(scene)
this.vIcon = scene.physics.add.sprite(x, y, 'airplane')
this.vLabel = scene.add.text(x, y + 15, name, TextStyle.PlaneName)
this.vLabel.setOrigin(0.5)
scene.add.existing(this)
}
fly() {
this.vIcon.setVelocity(10, 0)
}
preUpdate = (time, delta) => {
this.vLabel.x = this.vIcon.x
this.vLabel.y = this.vIcon.y + 15
}
}
A couple notes:
-
Updating the coords in
preUpdate
is simply a matter of re-running the same calculation that the constructor uses to position the item in the first place. If it really bothers you to copy/paste that math in two places, you could refactor the position calculations into private functions within the same module. Or you could probably not bother to set the position in the constructor at all, and just rely on math inpreUpdate
to set their positions on the next frame draw. That might result in a brief initial flash of glitchy layout, depending on how the lifecycle plays out. -
I’ve seen elsewhere that folks call
super.preUpdate
within their custom class’spreUpdate
method, but it throws when I try that (Phaser v3.54). So I just do the position assignment.
Frankly, I think it’s great. I feel like I’m making Phaser do almost all the work here.