In short: Is it possible to replace one (extant) animation with another animation? That is, such that calling “play” or “loop” and passing in the former animation’s ID results in the latter animation playing/looping? And if so, does this have consequences to be observed (e.g. with cleanup)?
To explain: I have a certain feature in a game that I’m working on that “freezes” an enemy in place. As part of this, it forces the enemy’s Actor-object to play its “standing” animation.
For the most part, this works well!
But I have one enemy that functions a little differently, and after a certain action has been performed by it, forcing the “standing” animation makes it look rather odd. (Long story.) As such, I’m thinking about, on taking that action, replacing its “standing” animation with another.
But… I’m not sure of how to do that, or indeed whether it can reasonably be done–or whether doing so might break something (such as Actor cleanup).
The issue isn’t a major one–it’s in a relatively-specific case, and it really only makes the enemy look a little janky in that case; it doesn’t currently break anything. But it would be a nice bit of polish if I could fix it.
It’s probably obvious enough, but my first inclination in a situation like this would be to assign some kind of boolean to catch the condition check, and then play a given animation frame range manually. IE actor.loop('Animation Name', fromFrame = 24, toFrame = 36)
I will wait to see if anyone else has ideas, however! As you say, there may be a better way…
That wouldn’t really work in my case, I fear.
At least not without putting a lot of code very specific to one type of enemy inside a section of code that generally doesn’t need to know about different types of enemy.
Basically, the thing that’s enacting the “freezing” is an object that can be applied to pretty much any enemy. (It gets added to a list of “updating effects” within the enemy.) From there, it acts on said enemy, using elements that are common to all enemies. It doesn’t “know” the specifics of the current enemy, and the enemies don’t “know” or act upon it (at least as regards its specific behaviour).
Although, writing that out, maybe I should revisit the logic of having it force the enemies into their “stand” animation. Perhaps I should just stop their current animation…
I might try that! If it works, it should obviate the issue, I imagine…
hmm… If it were me, I’d create a lookup of some kind that could act as an intermediary between passing animation input to the enemies and actually playing animation. That way you could dynamically override animations depending on various contexts. (In this case, being a particular enemy.)
It’d look something like this:
def __init__(self):
#...
self._anim_override_dict = {}
def play_animation(self, animation):
if animation in self._anim_override_dict.keys():
self.actor.loop(self._anim_override_dict[animation])
else:
self.actor.loop(animation)
#Then later on, in the class for this one particular enemy:
def freeze(self):
#...
self._anim_override_dict["standing"] = "other anim"
super().freeze()#plays "standing"
def unfreeze(self):
self._anim_override_dict.pop("standing")
The thing is, in my case it’s not the enemy that handles the “freezing”, or the change of animation. Instead, it’s a separate object that the enemy holds for a while, and which then acts on the enemy.
So there’s no equivalent of the “freeze” method in my enemy-classes for this specific class to override.
Instead, there’s a “freeze effect” class, which essentially tells the enemy to play its “stand” animation. (Amongst other effects.)
(The above behaviour comes from the “freeze effect” being a sub-class of a “stun effect” class. For the most part, looping “stand” makes sense when stunning things–but arguably less so when freezing things…
I’m thinking now that I might end up overriding that behaviour in favour of the freeze-class specifically calling a stop to the current animation…)
Hmm… With that structure, I’d probably implement a system where creatures/enemies listen for what effects are placed on them so they can add behavior in some cases. (Would also open up functionality like “This enemy takes additional damage when frozen” or “This enemy runs away when it recovers from being stunned.”)
But anyway…
Getting them to simply hold the pose does sound like a more intuitive solution.