Extending SpineGameObject...?

Hi Everyone,

Just wondering, how can I extend a SpineGameObject

For example, I usually create physics sprites by extending them like this:

class MySprite extends Phaser.Physics.Arcade.Sprite {...

(http://labs.phaser.io/edit.html?src=src/physics/arcade/extending%20arcade%20sprite.js)

I’m trying to do something similar with an SpineGameObject, but so far haven’t hit on the right formula yet. I assumed I could import SpineGameObject from SpinePlugin, and extend it like this:

import SpinePlugin from "../libs/phaser/SpinePlugin";
...
class MySprite extends SpinePlugin.SpineGameObject {...

… but no luck there (I’m getting an error message Super expression must either be null or a function, which looks like it’s just a default “I’m broken” message.)

Any suggestions on what I could try? I’m trying to create an Arcade physics object from a Spine animation.

Thanks!

I tried

class MySprite extends SpinePlugin.SpineGameObject {}

in the browser and it didn’t error. Try logging SpineLogin to see what you’re getting. The Super expression … error can mean you tried to extend undefined.

@samme … hmmm… thank you, I will dig a bit deeper and report back!

Yes, I thought that error might mean I was extending undefined, which is what I assumed SpinePlugin.SpineGameObject was… I will investigate! :grinning_face_with_smiling_eyes:

@sammeSpinePlugin was simply an empty object when I logged it - which of course makes no sense, so I realised I had a big problem somewhere!

It turns out I was importing SpinePlugin into the class completely incorrectly. I was importing it in my index.js like this:

import * as SpinePlugin from "./libs/phaser/SpinePlugin"; 

… which is good!

But, what I doing incorrectly was again importing it in my class file like this:

import SpinePlugin from "../libs/SpinPlugin";

… which was, I discovered, totally unnecessary and what was causing the conflict. Removing that import solved the problem, and I’m now able to extend SpineGameObject just like I thought I would be able to, like this:

class SpineThing extends SpinePlugin.SpineGameObject {

Works perfectly! :grinning_face_with_smiling_eyes:
Then I just need to call the super function with the correct arguments and manually add the object to the display list, like this:

scene.sys.displayList.add(this);
scene.sys.updateList.add(this);

(scene is the this which is being passed in as an argument from the Scene where this object is being created.)

I’m also able to extend SpineContainer like this:

class SpineThing extends SpinePlugin.SpineContainer {

One quirk with extending a SpineContainer however is that it seems like you need to add it to the display list without adding it to updateList:

scene.sys.displayList.add(this);

… adding it to updateList it throws an error.

1 Like

my index.js:

import "phaser/plugins/spine/dist/SpinePlugin.js" //alternative SpinePluginDebug.js

plugins: {
        scene: [
          { key: "SpinePlugin", plugin: window.SpinePlugin, mapping: "spine" },
        ],
      },

export class MangroveSpine extends window.SpinePlugin.SpineGameObject {

any prettier way? vscode can’t detect the link

Maybe ill try the functional approach though:

export function createMangrove(id, objectID = "Mangrove", scene, r, c) {

  const x = xGetCenter(c)
  const y = yGetCenter(r)
  const mangrove = addBodyspine(scene, x, y)
  mangrove.id = id
  mangrove.objectID = objectID
  mangrove.classID = getClassID(objectID)
  mangrove.setDepth(depthGet(r, mangrove.classID))
  mangrove.r = r
  mangrove.c = c`

i’m having hard time to understand how extend spinegameobject :

  • imported the plugin

my index.js:

import "phaser/plugins/spine/dist/SpinePlugin.js" //alternative SpinePluginDebug.js

plugins: {
        scene: [
          { key: "SpinePlugin", plugin: window.SpinePlugin, mapping: "spine" },
        ],
      },

and this is my class:

export default class slotSpine extends window.SpinePlugin.SpineGameObject { constructor(scene,x,y,sym){ //here set the props, how? setSkeleton is not function } }

How set the spine and the props of the object, i went through the docs but i was not able to understand how to do it

SpineGameObject’s args are (scene, plugin, x, y, key, animationName, loop).

Thx…

Hi. Is it correct to do it like this?

I extend my class Unit from SpineGameObject:

export class Unit extends SpineGameObject {
  constructor(
    scene: BattleScene,
    spinePlugin: SpinePlugin,
    x: number,
    y: number,
  ) {
    super(scene, spinePlugin, x, y, "skeleton-data", "skeleton-atlas");

   // ...
  }
}

Then to use it, I do it like this:

  new Unit(
    context,
    new SpinePlugin(context, new Phaser.Plugins.PluginManager(game), "spine.SpinePlugin"),
    x,
    y
  );

In my Phaser Game config, it’s like this:

  plugins: {
    scene: [
      {
        key: "spine.SpinePlugin",
        plugin: SpinePlugin,
        mapping: "spine",
      },
    ],
  },
// ...

I use the library import { SpinePlugin } from "@esotericsoftware/spine-phaser";

Would it be correct that even if I set in the config to have the SpinePlugin there, I am still creating a new one with new SpinePlugin(context, new Phaser.Plugins.PluginManager(game) when spawning a new unit?

thank you in advance.

Ok so I discovered a problem with using new Phaser.Plugins.PluginManager(game), "spine.SpinePlugin").

Generally, when you configure Phaser plugins in the game’s configuration, you don’t need to manually instantiate those plugins again in the game scenes unless you have a specific reason to do so. Instead, you should use the instance of the plugin that Phaser manages for you.

Instead of creating a new SpinePlugin instance when you create a new Unit , you should use the plugin instance that is already provided by the Phaser framework. Since you’ve mapped it as "spine" , you can access it through the scene’s plugin property like this:

export class Unit extends SpineGameObject {
  constructor(
    scene: BattleScene,
    x: number,
    y: number,
  ) {
    super(scene, scene.spine, x, y, "skeleton-data", "skeleton-atlas");
    // other initialization code...
  }
}

I hope it helps ya!

Pass the SpinePlugin class (function) to the game config to install it.

Pass the Spine plugin instance (usually this.spine) as the spinePlugin argument in the SpineGameObject constructor (or subclasses thereof).