phaser icon indicating copy to clipboard operation
phaser copied to clipboard

Matter Game Object Missing Types

Open jbromberg opened this issue 2 years ago • 3 comments

Version

  • Phaser Version: 3.55.2
  • Operating system: MacOS 12.0.1
  • Browser: Chrome

Description

When setting a Phaser game object to have matter physics, the types are missing in the object. I can call functions like setVelocity() and they work as expected, however TypeScript is telling me that this method does not exist on the game object.

Example Test Code

class Player extends Phaser.GameObjects.Container { // ... }

addPlayer(spawnPoint: VecXY, username: string, character: string) { const player = new Player(this.scene, spawnPoint, username, character); return this.scene.matter.add.gameObject(player); }

const player = factory.addPlayer({ x: 0, y: 0 }, "", "");

// This line of code is giving me an error player.setVelocity(0);

jbromberg avatar Feb 17 '22 16:02 jbromberg

What I'm really trying to do is have my Player class extend Phaser.Physics.Matter.Sprite but the super does not allow me to use a Phaser container to create it, only a single texture.

jbromberg avatar Feb 17 '22 16:02 jbromberg

I agree, this is a bug in the TypeScript definition.

To be more specific: the TypeScript type definition for the Phaser.Physics.Matter.Factory.gameObject function in phaser.d.ts is:

gameObject(
  gameObject: Phaser.GameObjects.GameObject, 
  options?: Phaser.Types.Physics.Matter.MatterBodyConfig | MatterJS.Body, 
  addToWorld?: boolean): 
  Phaser.Physics.Matter.Image | Phaser.Physics.Matter.Sprite | Phaser.GameObjects.GameObject;

The return type of Phaser.Physics.Matter.Image | Phaser.Physics.Matter.Sprite | Phaser.GameObjects.GameObject is incorrect. By inspecting the MatterGameObject function in MatterGameObject.js, I believe the correct TypeScript return type that should be specified is:

Phaser.GameObjects.GameObject &
Phaser.Physics.Matter.Components.Bounce &
Phaser.Physics.Matter.Components.Collision &
Phaser.Physics.Matter.Components.Force &
Phaser.Physics.Matter.Components.Friction &
Phaser.Physics.Matter.Components.Gravity &
Phaser.Physics.Matter.Components.Mass &
Phaser.Physics.Matter.Components.Sensor &
Phaser.Physics.Matter.Components.SetBody &
Phaser.Physics.Matter.Components.Sleep &
Phaser.Physics.Matter.Components.Static &
Phaser.Physics.Matter.Components.Transform &
Phaser.Physics.Matter.Components.Velocity

A workaround, until this is fixed, is to cast the return type. E.g. if you need to call setVelocity you would do this:

const player = this.scene.matter.add.gameObject(player) 
  as Phaser.GameObjects.GameObject & Phaser.Physics.Matter.Components.Velocity;
player.setVelocity(0);

BMorearty avatar Jul 26 '22 03:07 BMorearty

The fix I attempted (#6176) doesn't work because I directly modified the type definitions instead of modifying the types in JSDoc.

Unfortunately I don't know how to implement an intersection/mixin type in JSDoc so I'm going to leave this unfixed.

BMorearty avatar Jul 28 '22 17:07 BMorearty

Sadly there's just no way to do this with our current TS parser, so casting the return type is the correct (and only) way to do it for now, sorry. Roll-on Phaser 4 when everything is in TS to start with!

photonstorm avatar Nov 18 '22 21:11 photonstorm