Add a way to get a new spritesheet/animation reference from resource
mattjennings opened this issue · 3 comments
Context
Consider a scenario in which you are reusing an animation from the same Aseprite resource on multiple actors. The animation returned from getAnimation()
is shared, so the playback state is also shared across all actors using the same Aseprite resource.
https://codesandbox.io/s/excalibur-aseprite-shared-animation-reference-wjhuo8?file=/index.js
In the above example, there are 2 actors that should start on different frames of the same animation. Without the commented workaround, they share the animation state.
Proposal
Accept a parameter in resource.getAnimation()
or getSpritesheet()
that returns a new instance of the spritesheet or animation.
resource.getAnimation('abc', true)
resource.getSpriteSheet(true).getAnimation('abc')
I prefer the former, but I think having both would be good if you ever need the actual spritesheet reference too.
I'm happy to make a PR for this. I'm just unsure what to call the parameter. new
is a keyword so probably not that. recreate
?
@mattjennings Good find! This could definitely be a problem.
As a workaround you should be able to call ex.Animation.clone()
to make a new copy. Unfortunately I don't think ex.SpriteSheet
has a clone method (yet, but I'd also support adding one there).
I'd support a PR for a feature like this, I think supporting both getting a new copy of an ex.Animation
or ex.SpriteSheeet
would be good too 👍
Perhaps the optional parameter could be called clone
, copy
or maybe newInstance
?
oh! I didn't know there was a clone method on animations. In which case, since getAnimation().clone()
would suffice, I think just adding the same method to ex.SpriteSheet
would make more sense. And possibly also on the Aseprite resource itself?
ehh, it might get a little hacky trying to add clone()
to AsepriteResource
. This works, but is probably a bit forceful:
public clone() {
const clone = new AsepriteResource(this._resource.path, this.bustCache);
clone.data = this.data.clone(); // => AsepriteSpriteSheet.clone()
clone.rawAseprite = this.rawAseprite;
clone.image = this.image;
return clone
}