SKLabelNode 在指定时间显示文本
SKLabelNode display text at specified time
我正在制作一个场景,其中在 spriteKit 场景的底部逐行显示在场景背景中播放的歌曲的歌词。我尝试了多种不同的解决方案,但出于某种原因,每种解决方案中的一些歌词都没有显示或不同步。我试图使用 SKLabelNode 并使用 SKActions 在特定时间更改它的文本。必须有更简单的方法来做到这一点!?
这是我想出的函数:
import SpriteKit
let lyrics = SKLabelNode(fontNamed: "avenirnext")
func lyricSectionCreate(lnOneTxt: String, lnOneTime: Double, lnTwoTxt: String, lnTwoTime: Double, lnThreeTxt: String, lnThreeTime: Double, lnFourTxt: String, lnFourTime: Double, lnFiveTxt: String, lnFiveTime: Double, lnSixTxt: String, lnSixTime: Double, lnSevenTxt: String, lnSevenTime: Double, lnEightTxt: String, lnEightTime: Double, lnNineTxt: String, lnNineTime: Double, lnTenTxt: String, lnTenTime: Double){
lyrics.position = CGPoint(x:250, y: 25)
lyrics.zPosition = 5
//line one
let lnOne = SKAction.runBlock { () -> Void in
lyrics.text = lnOneTxt
}
runAfterDelay(lnOneTime){
lyrics.runAction(lnOne)
}
//line two
let lnTwo = SKAction.runBlock { () -> Void in
lyrics.text = lnTwoTxt
}
runAfterDelay(lnTwoTime){
lyrics.runAction(lnTwo)
}
//line three
let lnThree = SKAction.runBlock { () -> Void in
lyrics.text = lnThreeTxt
}
runAfterDelay(lnThreeTime){
lyrics.runAction(lnThree)
}
//line four
let lnFour = SKAction.runBlock { () -> Void in
lyrics.text = lnFourTxt
}
runAfterDelay(lnFourTime){
lyrics.runAction(lnFour)
}
//line five
let lnFive = SKAction.runBlock { () -> Void in
lyrics.text = lnFiveTxt
}
runAfterDelay(lnFiveTime){
lyrics.runAction(lnFive)
}
//line six
let lnSix = SKAction.runBlock { () -> Void in
lyrics.text = lnSixTxt
}
runAfterDelay(lnSixTime){
lyrics.runAction(lnSix)
}
//line seven
let lnSeven = SKAction.runBlock { () -> Void in
lyrics.text = lnSevenTxt
}
runAfterDelay(lnSevenTime){
lyrics.runAction(lnSeven)
}
//line eight
let lnEight = SKAction.runBlock { () -> Void in
lyrics.text = lnEightTxt
}
runAfterDelay(lnEightTime){
lyrics.runAction(lnEight)
}
//line nine
let lnNine = SKAction.runBlock { () -> Void in
lyrics.text = lnNineTxt
}
runAfterDelay(lnNineTime){
lyrics.runAction(lnNine)
}
//line ten
let lnTen = SKAction.runBlock { () -> Void in
lyrics.text = lnTenTxt
}
runAfterDelay(lnTenTime){
lyrics.runAction(lnTen)
}
}
func runAfterDelay(delay: NSTimeInterval, block: dispatch_block_t) {
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC)))
dispatch_after(time, dispatch_get_main_queue(), block)
}
哎呀!不是要走的路......想象一下如果有更多的行会发生什么?尽量避免重复代码。
以下是您可以根据这些数据预定义文本、延迟和刷新标签文本的方法(只需复制并粘贴代码以查看其工作原理):
import SpriteKit
class GameScene: SKScene {
let lyricsLabel = SKLabelNode(fontNamed: "ArialMT")
/*
Create an array of tuples (text,delay). You could go with struct as well.
*/
let lines:[(text:String, delay:NSTimeInterval)] = [
("Line 1" ,3.05),
("Line 2" ,1.05),
("Line 3" ,1.42),
("Line 4" ,0.87),
("Line 5" ,1.21),
("Line 6" ,0.12),
("Line 7" ,1.23),
("Line 8" ,1.23),
("Line 9" ,0.52),
("Line 10",2.12)
]
var currentLine = 0
override func didMoveToView(view: SKView) {
lyricsLabel.position = CGPoint(x:CGRectGetMidX(frame), y:CGRectGetMinY(frame) + 100)
addChild(lyricsLabel)
recursive()
}
/*
What is happening here is:
1. method recursive() is called
2. execution continues if there is more lines
3. label's text is updated (and currentLine is updated as well)
4. now we wait for a predefined duration, and recursive() is called again within itself, which means we jump to step 1 again, then go to step 2 etc...
*/
func recursive(){
guard currentLine < lines.count
else {
if actionForKey("aKey") != nil {
removeActionForKey("aKey")
}
return
}
lyricsLabel.text = lines[currentLine].text
let wait = SKAction.waitForDuration(lines[currentLine].delay)
let block = SKAction.runBlock({[unowned self] in
self.currentLine++
self.recursive()
})
let sequence = SKAction.sequence([wait, block])
let action = SKAction.repeatActionForever(sequence)
self.runAction(action, withKey: "aKey")
}
}
我正在制作一个场景,其中在 spriteKit 场景的底部逐行显示在场景背景中播放的歌曲的歌词。我尝试了多种不同的解决方案,但出于某种原因,每种解决方案中的一些歌词都没有显示或不同步。我试图使用 SKLabelNode 并使用 SKActions 在特定时间更改它的文本。必须有更简单的方法来做到这一点!?
这是我想出的函数:
import SpriteKit
let lyrics = SKLabelNode(fontNamed: "avenirnext")
func lyricSectionCreate(lnOneTxt: String, lnOneTime: Double, lnTwoTxt: String, lnTwoTime: Double, lnThreeTxt: String, lnThreeTime: Double, lnFourTxt: String, lnFourTime: Double, lnFiveTxt: String, lnFiveTime: Double, lnSixTxt: String, lnSixTime: Double, lnSevenTxt: String, lnSevenTime: Double, lnEightTxt: String, lnEightTime: Double, lnNineTxt: String, lnNineTime: Double, lnTenTxt: String, lnTenTime: Double){
lyrics.position = CGPoint(x:250, y: 25)
lyrics.zPosition = 5
//line one
let lnOne = SKAction.runBlock { () -> Void in
lyrics.text = lnOneTxt
}
runAfterDelay(lnOneTime){
lyrics.runAction(lnOne)
}
//line two
let lnTwo = SKAction.runBlock { () -> Void in
lyrics.text = lnTwoTxt
}
runAfterDelay(lnTwoTime){
lyrics.runAction(lnTwo)
}
//line three
let lnThree = SKAction.runBlock { () -> Void in
lyrics.text = lnThreeTxt
}
runAfterDelay(lnThreeTime){
lyrics.runAction(lnThree)
}
//line four
let lnFour = SKAction.runBlock { () -> Void in
lyrics.text = lnFourTxt
}
runAfterDelay(lnFourTime){
lyrics.runAction(lnFour)
}
//line five
let lnFive = SKAction.runBlock { () -> Void in
lyrics.text = lnFiveTxt
}
runAfterDelay(lnFiveTime){
lyrics.runAction(lnFive)
}
//line six
let lnSix = SKAction.runBlock { () -> Void in
lyrics.text = lnSixTxt
}
runAfterDelay(lnSixTime){
lyrics.runAction(lnSix)
}
//line seven
let lnSeven = SKAction.runBlock { () -> Void in
lyrics.text = lnSevenTxt
}
runAfterDelay(lnSevenTime){
lyrics.runAction(lnSeven)
}
//line eight
let lnEight = SKAction.runBlock { () -> Void in
lyrics.text = lnEightTxt
}
runAfterDelay(lnEightTime){
lyrics.runAction(lnEight)
}
//line nine
let lnNine = SKAction.runBlock { () -> Void in
lyrics.text = lnNineTxt
}
runAfterDelay(lnNineTime){
lyrics.runAction(lnNine)
}
//line ten
let lnTen = SKAction.runBlock { () -> Void in
lyrics.text = lnTenTxt
}
runAfterDelay(lnTenTime){
lyrics.runAction(lnTen)
}
}
func runAfterDelay(delay: NSTimeInterval, block: dispatch_block_t) {
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC)))
dispatch_after(time, dispatch_get_main_queue(), block)
}
哎呀!不是要走的路......想象一下如果有更多的行会发生什么?尽量避免重复代码。
以下是您可以根据这些数据预定义文本、延迟和刷新标签文本的方法(只需复制并粘贴代码以查看其工作原理):
import SpriteKit
class GameScene: SKScene {
let lyricsLabel = SKLabelNode(fontNamed: "ArialMT")
/*
Create an array of tuples (text,delay). You could go with struct as well.
*/
let lines:[(text:String, delay:NSTimeInterval)] = [
("Line 1" ,3.05),
("Line 2" ,1.05),
("Line 3" ,1.42),
("Line 4" ,0.87),
("Line 5" ,1.21),
("Line 6" ,0.12),
("Line 7" ,1.23),
("Line 8" ,1.23),
("Line 9" ,0.52),
("Line 10",2.12)
]
var currentLine = 0
override func didMoveToView(view: SKView) {
lyricsLabel.position = CGPoint(x:CGRectGetMidX(frame), y:CGRectGetMinY(frame) + 100)
addChild(lyricsLabel)
recursive()
}
/*
What is happening here is:
1. method recursive() is called
2. execution continues if there is more lines
3. label's text is updated (and currentLine is updated as well)
4. now we wait for a predefined duration, and recursive() is called again within itself, which means we jump to step 1 again, then go to step 2 etc...
*/
func recursive(){
guard currentLine < lines.count
else {
if actionForKey("aKey") != nil {
removeActionForKey("aKey")
}
return
}
lyricsLabel.text = lines[currentLine].text
let wait = SKAction.waitForDuration(lines[currentLine].delay)
let block = SKAction.runBlock({[unowned self] in
self.currentLine++
self.recursive()
})
let sequence = SKAction.sequence([wait, block])
let action = SKAction.repeatActionForever(sequence)
self.runAction(action, withKey: "aKey")
}
}