gamedevland/runner

Avoid appending additional properties to instances that do not support them

Opened this issue · 0 comments

Firstly, I've found your template and tutorials extremely helpful for getting started with using pixi and matter, so a huge thank you for this!

I've noticed here you are appending a custom property on to the Body instance provided by matter. Obviously this is totally valid in javascript (although some might argue it should be avoided), it's not something that's allowed in typescript.

I just wanted to raise this and suggest a couple of alternatives:

Use the body Id
Each body you create gets assigned a random number assigned to it's id property. Instead of appending the platform instance to the body, you could use the body id to look up the platform that has a matching id. For example:

// Platform.js
// ...
createBody() {
  this.body = Matter.Bodies.rectangle(this.width / 2 + this.container.x, this.height / 2 + this.container.y, this.width, this.height, {friction: 0, isStatic: true});
  Matter.World.add(App.physics.world, this.body);
  //this.body.gamePlatform = this;
}
// Platforms.js
// ...
findById(id) {
  return this.platforms.find(platform => platform.body.id === id);
}
// GameScene.js
// ...
onCollisionStart(event) {
  const colliders = [event.pairs[0].bodyA, event.pairs[0].bodyB];
  const hero = colliders.find(body => body.gameHero);
  // const platform = colliders.find(body => body.gamePlatform);
  const platform = colliders.find(body => !!this.platforms.findById(body.id));
  // ...
}

Use body labels

You can assign a label to your matter body when creating it. This could be useful for identifying the body when you expect only one of them to ever exist, for example, with the Hero.

// Hero.js
// ...
createBody() {
  this.body = Matter.Bodies.rectangle(
    this.sprite.x + this.sprite.width / 2, 
    this.sprite.y + this.sprite.height / 2, 
    this.sprite.width, 
    this.sprite.height, 
    {friction: 0, label: 'hero'} // Add label: 'hero' here
  );
  Matter.World.add(App.physics.world, this.body);
  // this.body.gameHero = this;
}
// GameScene.js
// ...
onCollisionStart(event) {
  const colliders = [event.pairs[0].bodyA, event.pairs[0].bodyB];
  // const hero = colliders.find(body => body.gameHero);
  const hero = colliders.find(body => body.label === 'hero');
  // ...
}

Disclaimer
I've just quickly typed this code straight into github, so I cant guarantee that applying only these changes works as described. I expect that there will be others areas of the code that might be affected by this change. It's intended more for descriptive purposes rather than a suggestion to "make these changes". Anyway, hope this helps you or someone else who stumbles upon this.