问题
I have an idle player animation and I want to do a smooth transition between some animations. The idle animation is the default one and from that transition I want to be able to switch to another state(let's say fight) and then back to idle. The code for the idle character animation is currently like :
self.addChild(playerAnimation)
playerAnimation.runAction(SKAction.repeatActionForever(
SKAction.animateWithTextures(playerAnimationManager.idleManAnimation.textureArray, timePerFrame: 0.1)))
Now, this is scheduled to go on forever for now, but I would need to intercept it and add a new animation on top of that (which is the same character, in a new state). I was thinking that I should stop the idle animation, switch to the new one and then back to idle when finished but I am not convinced that this is the best way of chaining animations and I haven't really found a good resource explaining how to go about it.
Any suggestions ? Thanks !
回答1:
Depending on how short your texture array is, you might be able to do this.
I will try to explain without code seeing how I use objective C
and you use Swift
First make a property or variable that can be called by any subroutine in this class file. It should be
Boolean
and should be set toNO
. You could call itidleFlag
.Next make a method that changes the animation to fight mode. This change would be by removing the idle animation and replacing it with the fight animation. This method also set's
idleFlag
toNO
. Let's call the method "beginFightAnim
"- And last, in your
repeatActionForEver
idle animation, right after youranimateWithTextures
animation, add arunBlock
animation. In this block define a static variable (one that will be remembered in the calling of the block over and over) and increment it by +1, add an "if statement" that looks something like this ->if (my_static_var == number_of_frames_in_texture_animations && idleFlag)
. And in the "if statement" set the static variable to 0 and call "beginFightAnim
"
After this all you have to do to change the animation is set idleFlag
to YES
.
Hope it works!
If you have any problems, please comment below.
回答2:
I want to do a series of examples to make it easier to understand the matter. Suppose you have your node called playerAnimation
, a typical atlasc with a plist where you have
player-idle1.png
player-idle2.png
player-idle3.png
...
If you want to intercept in real-time your animation to know what frame is running in that moment you can do:
override func update(currentTime: CFTimeInterval) {
if String(playerAnimation.texture).rangeOfString("player-idle") != nil {
print(String(playerAnimation.texture))
}
}
At this point, after you have assigned a "key" to your action (withKey:"idleAnimation"
) you could stop your specific idle action when you preefer to start the other next animation.
Another good thing is to build a structure to know everytime your player status and modify this variable each time you launch a new action or animation:
enum PlayerStatus: Int {
case Idle = 1
case Fight = 2
case Run = 3
case Jump = 4
case Die = 5
...
}
var currentStatus: PlayerStatus!
来源:https://stackoverflow.com/questions/38557040/proper-transition-between-spritekit-animations