How to Extend Phaser Component Functionality

is there a good way to extend phaser component functionality ?
for example i usually extends an object functionality through code below

// size_extension.js
const SizeExtension = {
    /** @returns {number} */
    widthAspectRatio: function ()
    { return this.width / this.height },

    /** @returns {number} */
    heightAspectRatio: function ()
    { return this.height / this.width },
}
export default SizeExtension;

which then later referenced and called through

// game_scene.js
import SizeExtension from 'size_extension.js'
export default class GameScene extends Phaser.Scene
{
   create()
   {
        const img = this.add.image();
        Object.assign(img, SizeExtension);
        img.setDisplaySize(img.widthRatio *3 , img.widthRatio *3 *img.height);
   }
|

the problem i found from doing this is i need to add type SizeExtension to jsdoc so it would become somewhat typesafe.

i am used with unity and C# with extension method. but js with it’s own specification seems to differ from my usual coding style.

would love to see other people opinion on how they handle this problems

You can do

Object.assign(Phaser.GameObjects.Image.prototype, SizeExtension);

if you like.

where’s this method should be called ? i believe it is applied globally within the phaser, or am i wrong?

still ,webstorm gives warning when i’m trying to attach jsdoc type tag to field. it would still requires me to add SizeExtension to the jsdoc type

You could do it before new Phaser.Game().

There’s no problem doing this in JS, but if you have a static type checker then it’s going to complain.

thanks that clears up bunch of my code from Object.assign statement

i find these static type checker to be very useful to cleanly code and navigate through them.
is there any workaround with these static type checker complain ?

or is it just straight better to migrate to typescript instead ?

I too was used to C# when starting with Phaser and after struggling with javascript for a while I changed to typescript and felt right at home. You might find this to be the case for you as well! (In addition, next major release of Phaser is developed using typescript)

1 Like

Also, you can use wrappers for adding components to an object. It is the same technique we use in Phaser Editor to add components in the Inspector of the Scene Editor: https://help.phasereditor2d.com/v3/scene-editor/user-components.html

1 Like

thanks a lot.this does looks nice and easily implemented.
my friend do provide similar but different approach like these. but i believe yours are way better since his are creating inheritance with additional handling which add additional complexity when using it.

but naming would turn quite weird. since most of my stuff is extending functionality of phaser component. like SizeExtension, TransformExtension, group extension. and it only have small code snippet to utilize when needed.

1 Like

By the way, you can take a look to this article. I think with TypeScript you can do something similar to C#: https://medium.com/my-coding-life/extension-method-in-typescript-66d801488589

so i’ve tried what the article told me. and it does work like c# extension method.

but i got concerned since this is javascript which doesn’t compile.

it got me thinking that everytime i call extension scripts every property assignment are done repeatedly. does this will affect performance in the long run when those extension script are going to be called in many scripts where extension method are going to be required. and missing it would result in an error.

does typescript compilation help with this ? as of converting multiple extension script call into 1 call.

i’m still on migration process to typescript and so far what i felt is more organized code :smiley:

You can do the same with JavaScript. In the end, TypeScript compiles to JS.

In JavaScript, you can extend the prototype too, and you don’t need to do it for every object, you do it just once.

1 Like

but those prototype extension will have global scope. and that’s the what i’m concerned with.

what if there are case where another developer might add same property as what i already did. and it gets overwritten and mess with many functionality related to it.

1 Like