swift - 我在 SpriteKit 上的 scheduledTimer 有问题

标签 swift timer sprite-kit

我正在用 Swift 和 SpriteKit 做一些实验。

我有 4 张硬币图片。 (硬币 1,硬币 2,...)。我想在屏幕上的随机位置生成一个随机硬币并让它淡出。我想每 3 秒重复一次这个 Action 。这是代码,它运行良好。

    class GameScene: SKScene {

// creating a playable area
let gameArea: CGRect
override init(size: CGSize) {

    let maxAspectRatio: CGFloat = 16.0/9.0
    let playableWidth = size.height / maxAspectRatio
    let gameAreaMargin = (size.width - playableWidth)/2
    gameArea = CGRect(x: gameAreaMargin, y: 270, width: playableWidth, height: size.height - 270)

    super.init(size: size)
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}


func random() -> CGFloat {
    return CGFloat(Float(arc4random()) / 0xFFFFFFFF)
}
func random(min: CGFloat, max: CGFloat) -> CGFloat {
    return random() * (max-min) + min
}


func spawnAndFadeCoins() -> SKSpriteNode{

    let randNum = arc4random()%4 + 1
    let coin = SKSpriteNode(imageNamed: "coin\(randNum)")

    if randNum == 4 {
        coin.zPosition = 10
    }
    else {
        coin.zPosition = 5
    }
    coin.name = "coin\(randNum)"
            let randomX = random(min: gameArea.minX + coin.size.width/2,
                         max: gameArea.maxX - coin.size.width/2)
            let randomY = random(min: gameArea.minY + coin.size.height/2,
                         max: gameArea.maxY - coin.size.height/2)
            coin.position = CGPoint(x: randomX, y: randomY)

    let disappear = SKAction.fadeOut(withDuration: 1.0)
    coin.run(SKAction.repeatForever(disappear))
    self.addChild(coin)
    return(coin)

}
    override func didMove(to view: SKView) {

    let background = SKSpriteNode(imageNamed:"bg")
    background.size = self.size
    background.position = CGPoint(x:self.frame.size.width/2, y: self.frame.size.height/2)
    background.zPosition = 0
    self.addChild(background)

    var _ = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(GameScene.spawnAndFadeCoins), userInfo: nil, repeats: true)

        }
    }

但是,当我为每个硬币添加一个指定其名称的标签时,奇怪的事情发生了:每 3 秒后,3 个硬币同时出现在屏幕上。标签贴在这 3 枚硬币中的一枚上,它甚至没有正确说出硬币的名称。这是新代码:

    class GameScene: SKScene {

// creating a playable area
let gameArea: CGRect
override init(size: CGSize) {

    let maxAspectRatio: CGFloat = 16.0/9.0
    let playableWidth = size.height / maxAspectRatio
    let gameAreaMargin = (size.width - playableWidth)/2
    gameArea = CGRect(x: gameAreaMargin, y: 270, width: playableWidth, height: size.height - 270)

    super.init(size: size)
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}


func random() -> CGFloat {
    return CGFloat(Float(arc4random()) / 0xFFFFFFFF)
}
func random(min: CGFloat, max: CGFloat) -> CGFloat {
    return random() * (max-min) + min
}


func spawnAndFadeCoins() -> SKSpriteNode{

    let randNum = arc4random()%4 + 1
    let coin = SKSpriteNode(imageNamed: "coin\(randNum)")

    if randNum == 4 {
        coin.zPosition = 10
    }
    else {
        coin.zPosition = 5
    }
    coin.name = "coin\(randNum)"

            let randomX = random(min: gameArea.minX + coin.size.width/2,
                         max: gameArea.maxX - coin.size.width/2)
    let randomY = random(min: gameArea.minY + coin.size.height/2,
                         max: gameArea.maxY - coin.size.height/2)
    coin.position = CGPoint(x: randomX, y: randomY)


    let disappear = SKAction.fadeOut(withDuration: 1.0)
    coin.run(SKAction.repeatForever(disappear))
    self.addChild(coin)
    return(coin)

}

func spawnAndFadeLabels() -> SKLabelNode{
    let label = SKLabelNode()
    label.text = "\(spawnAndFadeCoins().name)"
    label.zPosition = 15
    label.color = SKColor.white()
    label.fontSize = 60
    label.position = spawnAndFadeCoins().position

    let disappear2 = SKAction.fadeOut(withDuration: 1.0)
    label.run(SKAction.repeatForever(disappear2))


    self.addChild(label)
    return(label)
}




override func didMove(to view: SKView) {

    let background = SKSpriteNode(imageNamed:"bg")
    background.size = self.size
    background.position = CGPoint(x:self.frame.size.width/2, y: self.frame.size.height/2)
    background.zPosition = 0
    self.addChild(background)

    var _ = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(GameScene.spawnAndFadeCoins), userInfo: nil, repeats: true)

    var _ = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(GameScene.spawnAndFadeLabels), userInfo: nil, repeats: true)



        }
    }

你能帮我解开这个谜团吗?提前致谢。

最佳答案

问题是您在 spawnAndFadeLabels 中调用了 spawnAndFadeCoins 两次:

func spawnAndFadeLabels() -> SKLabelNode{
    let label = SKLabelNode()
    label.text = "\(spawnAndFadeCoins().name)" <-- here!
    label.zPosition = 15
    label.color = SKColor.white()
    label.fontSize = 60
    label.position = spawnAndFadeCoins().position <-- and here!

    let disappear2 = SKAction.fadeOut(withDuration: 1.0)
    label.run(SKAction.repeatForever(disappear2))


    self.addChild(label)
    return(label)
}

我认为你可以做的一件事是:

只有一个定时器:

runAction(SKAction.repeatForever(SKAction.sequence([SKAction.wait(forDuration: 3), SKAction.run(spawnAndFadeCoins)])))

我这里使用了SKAction,因为在spritekit中不推荐使用Timer

现在只有 spawnAndFadeCoins 每三秒调用一次。然后,将 spawnAndFadeLabels 更改为:

func spawnAndFadeLabels(of node: SKSpriteNode) -> SKLabelNode{
    let label = SKLabelNode()
    label.text = "\(node.name)"
    label.zPosition = 15
    label.color = SKColor.white()
    label.fontSize = 60
    label.position = node.position

    let disappear2 = SKAction.fadeOut(withDuration: 1.0)
    label.run(SKAction.repeatForever(disappear2))
    self.addChild(label)
    return(label)
}

spawnAndFadeCoins 更改为:

func spawnAndFadeCoins() -> SKSpriteNode{

    let randNum = arc4random()%4 + 1
    let coin = SKSpriteNode(imageNamed: "coin\(randNum)")

    if randNum == 4 {
        coin.zPosition = 10
    }
    else {
        coin.zPosition = 5
    }
    coin.name = "coin\(randNum)"

            let randomX = random(min: gameArea.minX + coin.size.width/2,
                         max: gameArea.maxX - coin.size.width/2)
    let randomY = random(min: gameArea.minY + coin.size.height/2,
                         max: gameArea.maxY - coin.size.height/2)
    coin.position = CGPoint(x: randomX, y: randomY)


    let disappear = SKAction.fadeOut(withDuration: 1.0)
    coin.run(SKAction.repeatForever(disappear))
    self.addChild(coin)
    spawnAndFadeLabels(of: coin) <-- This line is added!
    return(coin)

}

我想这就是你想要的。

关于swift - 我在 SpriteKit 上的 scheduledTimer 有问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41607025/

相关文章:

java - 线程 sleep 阻止我的 Swing 应用程序执行

具有定时器控制的线程池操作的 C# WinService

ios - 遍历 SKNode 的所有子节点?

swift 3 (SpriteKit) : Aligning SKPhysicsBody to SKShapeNode

ios - iOS7中的SpriteKit animateWithTextures不起作用

arrays - 快速性能 : map() and reduce() vs for loops

swift - 无法将 'Void'类型的值(也称为 '()')分配给 '() -> Void'类型

javascript - 在 WKWebView(iOS,Swift)中使用本地 Javascript 源加载本地 HTML

swift - 在所有变量为零的情况下运行代码

forms - Powershell:从后台作业结果更新 GUI