我在SpriteKit上的scheduledTimer出了点问题

时间:2017-01-12 07:03:43

标签: swift timer sprite-kit

我正在用Swift和SpriteKit试验一些东西。

我有4张硬币图片。 (coin1,coin2,...)。我想在屏幕上的随机位置产生随机硬币并让它淡出。我想每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)

}
    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个硬币。标签放在这三个硬币中的一个上,它甚至没有正确说出硬币的名称。这是新代码:

    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)



        }
    }
你可以帮我解开这个谜吗?提前谢谢。

1 个答案:

答案 0 :(得分:2)

问题是您在spawnAndFadeCoins中再次致电spawnAndFadeLabels

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)

}

我认为这是你想要的。