I’m making an airline tycoon game. I’m trying to draw an 8-bit airplane with a tail number beneath it, and then I want to make it fly from A to B over the course of a couple of minutes.
I have a version working that uses setVelocity
on a physics sprite, but the tail number text does not move with the plane. And I’m realizing I don’t know what is the best practice for assembling complex visualizations out of the basic displayable Phaser constructs. So that’s my real question, but I’ll use Plane as my example.
Plane
is a custom class. Until I needed Planes to move, Plane
extended Sprite
:
class Plane extends Phaser.GameObjects.Sprite {
constructor( scene, x, y, tailNumber ) {
super(scene, x, y, 'airplane')
this.vLabel = scene.add.text(x, y + 15, tailNumber, TextStyle.PlaneName)
this.setInteractive()
}
}
So, this
is the airplane Sprite, and this.vLabel
holds a reference to a Text GameObject.
Now I need to make Planes move, so I added no-gravity physics to the game and modified Plane
to be the physics version of Sprite
so I could setVelocity
to make it move:
class Plane extends Phaser.Physics.Arcade.Sprite {
constructor( scene, x, y, tailNumber ) {
super(scene, x, y, 'airplane')
scene.physics.world.enableBody(this, Phaser.Physics.Arcade.DYNAMIC_BODY)
this.vLabel = scene.add.text(x, y + 15, tailNumber, TextStyle.PlaneName)
this.setInteractive()
}
fly = () => {
this.setVelocity(/*...*/)
}
}
That airplane moves, but the tail number doesn’t.
It has always seemed kind of hokey to me that my custom game items are each built around some kind of “primary” renderable construct (such as a sprite), with a bunch of additional object references dangling off them. For one thing, it means that click handlers only fire when the gameobjectup
event occurs over the “primary” construct: if someone clicks the tail number text, it won’t fire as a click on the Plane instance. (I have this same problem with Airport objects, which have a visible icon representing the airport, plus text of the city name, and some crude adjacent shapes to represent the condition of the airport. Clicking on the icon counts as a click on the city, because the icon is the “primary” element of the City object, but clicking the label text or the shapes does not count.)
I was looking at the Container class, but there’s a scary warning about performance costs, which is not the kind of thing I would expect to see on something we’re supposed to use as our bread-and-butter. And I don’t require the nicety of local coordinates for my purposes.
I tried converting Plane to extend Phaser.GameObjects.GameObject
, and then make the constructor create the physics sprite and the piece of text, but it crashes at runtime:
class Plane extends Phaser.GameObjects.GameObject {
constructor( scene, x, y, tailNumber ) {
super(scene)
// blows up immediately
}
}
// Uncaught TypeError: gameObject.preUpdate is undefined
How can I make the tail number text move with the plane graphic? What would the constructor look like for a custom game object that needs a physics sprite, a non-physics image, some text, and maybe some additional shapes? What is a good general pattern here?