Jump to content

Sprite errors when adding animation: Cannot read property 'getFrameIndexes' of null


bdickason
 Share

Recommended Posts

I've been battling this problem for the past 24h and figured it was worth asking for help.

I've got a class called Character that extends Phaser.Sprite and is used in a few States (Character Select->Play) for my game. When  I instantiate new Characters in the Select class or Play class, they work great as expected. However, when I load the Select state and select a character (which calls the 'Play' state), the Character class errors upon instantiating a new character in the new state with the following message:

Uncaught TypeError: Cannot read property 'getFrameIndexes' of null
    at Phaser.AnimationManager.add (phaser-split.js?2ffb:49401)
    at Character.loadData (character.js?9c96:59)

If I call the 'Play' state directly, the character loads properly and doesn't give any errors. So it only seems to be happening when going from one state to another, which is puzzling me.

I've tried every route of debugging possible and the only solution I can find seems to be not loading the data dynamically from my server.

Currently, the animation data in my Character class gets loaded via socket.io which is called in the constructor:

  window.socket.on(`data:load:${name}`, (data) => {
      // Listen to data updates for this character
      this.loadData(data)
    })

    window.socket.emit('data:request', name) // Request new data from the server

The loadData function then loops through the data and adds the animation frames:

  loadData(data) {
    // Grab data from server for this character from its definition file
    for(let anim in data.anims) {
      this.animations.add(anim, data.anims[anim].frames, data.anims[anim].speed)
    }
  }

The error above occurs on the first animation I want to add. If I look at the this.animations object, it doesn't have a 'sprite' set and most values are null.

Any help would be appreciated. I've stripped out most of my code at this point and am now just stuck. I've searched a bunch (here/google/stackoverflow) and the only solutions to people running into similar problems seem to be to make sure you're passing this.game into your sprite, which I'm doing :)

Actual code (Github)
Play (state): https://github.com/stormsword/stormsword/blob/classes/lib/client/game/play.js

Character (sprite): https://github.com/stormsword/stormsword/blob/classes/lib/client/game/char/character.js

Link to comment
Share on other sites

2 hours ago, samme said:

Is it possible you're working on a sprite that's already been destroyed?

Hmm that's an interesting idea. I had thought about the sprite not being loaded in time (i.e. I was calling animation.start before it's fully setup) but not that it was already destroyed. Will play around with that tonight, thanks!!!

Link to comment
Share on other sites

10 hours ago, samme said:

Is it possible you're working on a sprite that's already been destroyed?

That was it!! I didn't realize that my old sprites from the first state stuck around in memory in the second state! I checked the 'id' field (unique identifier i assign to each sprite) and it was one from the first state o_O

Thanks so much :D

If anyone stumbles upon this in the future, the old sprites were sticking around and had an event that listened any time data was loaded for that class:

window.socket.on(`data:load:${name}`

My next state instantiated a new instance of the same sprite so when it spawned, the old sprite was destroyed but was still listening to this event.

To solve this in the short term, I changed this from a `window.socket.on` to a `window.socket.once` and I'll investigate memory management to see how/when sprites are destroyed going forward.

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...