Jump to content

How to reuse game.anims animations?


johncl
 Share

Recommended Posts

I see that Phaser 3 now uses shared animations on the game/scene object itself, but I am stumped at how you can actually reuse these for several sprites that have the same index offsets relative to each other?

For example, with this I am using a spritesheet where the toon sprite is at index 128, 3 frames each direction (offset 16 sprites down). But the method takes the sprite sheet name as well as an explicit start and end.
Considering each of these get their own name, I cant really see how they can be reused for another sprite where I want to just offset the animation to another part of the sprite sheet or another sheet for that matter?
I am missing something? As it is now I have to generate a lot of game.anims entries with keys for each type of toon which I find odd - since they might as well then just have been defined on the sprite itself like Phaser 2?

        var so = 128;
        game.anims.create({
            key: 'down', frameRate: 8, repeat: -1,
            frames: game.anims.generateFrameNumbers('toons', { start: so, end: so+2 })
        });    
        game.anims.create({
            key: 'left', frameRate: 8, repeat: -1,
            frames: game.anims.generateFrameNumbers('toons', { start: so+16, end: so+16+2 })
        });    
        game.anims.create({
            key: 'right', frameRate: 8, repeat: -1,
            frames: game.anims.generateFrameNumbers('toons', { start: so+32, end: so+32+2 })
        });    
        game.anims.create({
            key: 'up', frameRate: 8, repeat: -1,
            frames: game.anims.generateFrameNumbers('toons', { start: so+48, end: so+48+2 })
        });    

To put it into context, this is from the new Phaser 3 tutorial pages:

https://phaser.io/tutorials/making-your-first-phaser-3-game/part5

Quote

"Extra Info: In Phaser 3 the Animation Manager is a global system. Animations created within it are globally available to all Game Objects. They share the base animation data while managing their own timelines. This allows you to define a single animation once and apply it to as many Game Objects as you require. This is different to Phaser 2 where animations belonged specifically to the Game Objects they were created on."

If the animation contains both absolute indexes as well as the sprite sheet, I cant really see how this is the case? Again, I am likely missing something. :)

Link to comment
Share on other sites

Perhaps this example can give some inspiration.  It appears to be a Phaser plugin, similar to a JavaScript mixin, where a single function (or extended class in this example) becomes a global properties extension for other game objects...

https://labs.phaser.io/edit.html?src=src/plugins\start and stop a plugin.js

 

As for another idea - You can  try to create a reusable function that takes parameters, and simply call it  when needed.  Look at my last example in the given thread...

 

 

 

 

 

Link to comment
Share on other sites

Ok, yes I guess I can build an extension and drop the whole Phaser 3 animation system. Just feels like a shortcoming that in order to play an animation it seems you do this:

sprite.anims.play('up', true);

You have to specify a key that is configured globally on the game.anims object. To me it looks like you have to make a separate key for each 'up' then, 'player_up', 'player_with_different_graphics_up', 'monster1_up' etc - even if they all could essentially share the same index offsets using some start index set on the sprite itself.

From the Phaser 3 tutorial I linked I even got the impression that was the whole reason for making the animation manager a global system, to encourage reuse.

Link to comment
Share on other sites

Reading through the source code for AnimationManager and Animation - I see its almost there but no quite. I was fooled by this one:

sprite.anims.play('up', true, 5);

Thinking that perhaps the index there at the end was the offset that would be added to all animation frames on playback, but no such luck - it only sets the start frame within the configured animation that 'up' was created with (even checking if its above, and if so setting it to 0).

Actually if an animation wasn't also set up with a texture key you would have been able to set the texture on the sprite once (which you have to do anyway when creating the sprite) and just split each toon into separate sprite sheets and reuse all animations for all toons as they animation system could only just set which frame the sprite has to show.

I will likely just write my own animation system then to simplify this.

Link to comment
Share on other sites

If you've a sprite sheet with 6 different animations within it, for say 6 different types of monster, then absolutely yes, you'd have to define each one with a unique key ('monster1Up', 'monster2Up', etc). If you then have 1000 of those monsters running around your world, they are all sharing the same 6 global animations. In v2 you would have had to have created 1000 unique animations, one per monster instance. So yes, v3 will re-use global animation data across as many Game Objects as you like, without duplicating all of the frames and other stuff.

More importantly, an animation can consist of multiple frames from multiple textures, which would be impossible to define if they worked as you expected (i.e. a frame and an offset). Indeed, offsets only apply for sprite sheets and are not much use for texture atlases, where frames can be spread across multiple textures to optimize space. Because of this, the animation frames are tightly bound to the texture itself.

Feel free to write your own animation system, that's the whole point of an open source project, you replace the bits that don't do what you need. Just understand that your requirement is highly specific to your use-case and the way your assets are defined, which is quite unusual.

Link to comment
Share on other sites

Thanks for the reply. Yes I see that the animation system in Phaser is built for a richer purpose besides the one I had in mind. It is certainly good that they can be shared between instances of each toon "type". Once I had added the code to generate variations for each type it worked fine for now. I guess I'd need to have a lot of types to worry about the space it requires which isn't much anyway. I guess I am just very easily hung up on optimizing both memory usage and complexity from the old days. :)

Link to comment
Share on other sites

Made a feature request : https://github.com/photonstorm/phaser/issues/4090

// 

//create shared animations
createAnimations([player, monster, npc], "right", [0,1,2,3])
createAnimations([player, monster, npc], "up", [0,1,2,3])
createAnimations([player, monster, npc], "down", [0,1,2,3])
createAnimations([player, monster, npc], "left", [0,1,2,3])

function createAnimations(texture, animationName, frames) {
    for (var i = 0; i < texture.length; i++) {
        this.anims.create({
            key: texture[i] + animationName,
            frameRate: 5,
            frames: this.anims.generateFrameNumbers(texture, {
                frames: frames
            })
        });
    }
}

//sprites have a .textureKey property and when they play animation,
sprite.anims.play(this.textureKey+animationName);

But yeah, duplicating objects, I wonder how it's going to impact performance.

Link to comment
Share on other sites

If you're at the point where 12 tiny 4 frame Animation objects are a performance consideration, I'd say you've much more serious things to worry about.

Especially considering the alternative, which is that you have 1 single Animation object, but every single call to 'play' now has to check for a frame offset value, and the value needs to be stored and applied every single time the frame of the animation changes, multiplied by the number of Game Objects using animations.

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

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