I have a game scene that consists of animations that occur in sync with the content of a song. One of the actions I'm trying to set up is in relation to the lyrics of the song which are displayed using an SKLabelNode. What I want to do is is toggle between two animations based on whether or not there are characters in the LabelNode (the singer stops "singing" and waits). I have this in the update method:
var singerActive = false
var lyricsLabel = SKLabelNode()
override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
if lyricsLabel.text?.characters.count == 0{
singerActive = false
}else{
singerActive = true
}
let sings = SKAction.runBlock { () -> Void in
self.singer.runAction(SKAction.fadeAlphaTo(1, duration: 0.1))
self.singerIdle.runAction(SKAction.fadeAlphaTo(0, duration: 0.1))
}
let singerInactive = SKAction.runBlock { () -> Void in
self.singer.runAction(SKAction.fadeAlphaTo(0, duration: 0.1))
self.singerIdle.runAction(SKAction.fadeAlphaTo(1, duration: 0.1))
}
var stopper = true
if singerActive && stopper{
stopper = false
singer.runAction(sings)
}
if singerActive == false && stopper == false{
stopper = true
singer.runAction(singerInactive)
}
}
Unfortunately, this doesn't seem to work. The active singer state works, but the inactive state fails to trigger when the character count == 0. I put the "stopper" bool in there in order to ensure that the SKAction doesn't get called continuously as it's in the update method. I'm fairly new to Swift and SpriteKit so any help would be greatly appreciated.
Your stopper code is breaking everything, you want to do something like this:
override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
if lyricsLabel.text?.characters.count == 0{
singerActive = false
}else{
singerActive = true
}
let sings = SKAction.runBlock { () -> Void in
self.singer.runAction(SKAction.fadeAlphaTo(1, duration: 0.1))
self.singerIdle.runAction(SKAction.fadeAlphaTo(0, duration: 0.1))
}
let singerInactive = SKAction.runBlock { () -> Void in
self.singer.runAction(SKAction.fadeAlphaTo(0, duration: 0.1))
self.singerIdle.runAction(SKAction.fadeAlphaTo(1, duration: 0.1))
}
if singerActive{
singer.removeAllActions()
singer.runAction(sings)
}
else{
singer.removeAllActions()
singer.runAction(singerInactive)
}
}
But this is also bad because this means that you are always running an action on every update. You may want to rework your code so this isn't happening.
So you need to do something like this:
override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
if lyricsLabel.text?.characters.count == 0{
singerActive = false
}else{
singerActive = true
}
let sings = SKAction.runBlock { () -> Void in
self.singer.runAction(SKAction.fadeAlphaTo(1, duration: 0.1))
self.singerIdle.runAction(SKAction.fadeAlphaTo(0, duration: 0.1))
}
let singerInactive = SKAction.runBlock { () -> Void in
self.singer.runAction(SKAction.fadeAlphaTo(0, duration: 0.1))
self.singerIdle.runAction(SKAction.fadeAlphaTo(1, duration: 0.1))
}
if singerActive && singerIdle.alpha = 1{
singer.removeAllActions()
singerIdle.alpha = 0.99;
singer.runAction(sings)
}
else if !singerActive && singer.alpha = 1{
singer.removeAllActions()
singer.alpha = 0.99;
singer.runAction(singerInactive)
}
}
Now we only call it when our alpha states are at 1