allow custom body classes
For now there is nice api with world.createBody(), but there is no typed way to create custom body classes and add it to the world. When I say typed I mean that there no public addBody method, which has described definition in typescript, while actualy world has method _addBody.
Why do I need this? I wanna add validation to body.setUserData() to improve type hinting and code consistency. Most convenient way is to make a class whick extends Body and redeclare setUserData method.
By validation do you mean type-safety, or actualling validating data? For just type-safety, could you use something like this:
declare module "planck" {
interface Body {
setUserData(data: MyDataType): void;
getUserData(): MyDataType;
}
}
Yes, when I need only type safety this is good way, but sometimes I need actualy validating data, or for example have default value:
public getUserData(): MyDataType {
const userData = super.getUserData();
if (!userData) {
this.setUserData({});
}
return super.getUserData() as MyDataType;
}
Another case is when i have complex data and wanna have shortcuts to its parts:
public setSprite(sprite?: Sprite): this {
this.getUserData().sprite = sprite;
return this;
}
public getSprite(): Sprite|undefined {
return this.getUserData().sprite;
}
Another advantage of custom classes is that you can create your own interface to keep code-constistency of project, e.g.:
body.fixture() // custom method, that returns builder instance with method chaining
.fromSprite(sprite)
.appendToBody();
How about building your game data model and classes in plain JS, and then use planck to move physical objects?
Like this example: https://github.com/piqnt/polymatic-example-watermelon/blob/main/src/Physics.ts
No, I havn't, but how it solves cusomisation problem? When I need custom Body, Fixture or other class there is only dirty ways like using private non-documented methods or modifying prototypes. Why not add clearly way if it anyway possible via dirty ways?
In the examples you provided above you are using inheritance to use physics classes. I recommend composition over inheritance. That is:
- design game classes however you need
- create corresponding physics object for each game object
- keep a reference to physics object in your game object
- use userData to keep a reference from physics objects to game objects
With composition you can also add other things to your game classes.
I'm already considering improving addBody and making it public in next major release, but I still do not recommend customizing physics classes with non-physics code.
I still do not recommend customizing physics classes with non-physics code.
I understand that and understand why, and agreed with you. I am actually doing composition in my projects, e. g. Player have property body, but sometimes I need custom methods with physics (but not with game logic), like
// Player.ts, contructor of the class
...
this.body.fixture() // returns custom builder-class that collects data in a way that is convenient for me
.dencity(.5)
.rigidity(.3)
.circle(5)
.appendToBody(); // and creates fixture here, actually body.createFixture() under the hood
I'm already considering improving addBody and making it public in next major release
That is what I wanted to hear, thank you! Should I close this issue now? (never opened issues before, idk lol)
Sounds great! Meanwhile, just for builder what about creating a function that returns a wrapper around fixture definition:
fixtureBuilder() .density(.5) .rigidity(.3) .circle(5) .appendToBody(body);