Swift 不在SpriteKit中执行纹理的简单动画

Swift 不在SpriteKit中执行纹理的简单动画,swift,xcode,sprite-kit,Swift,Xcode,Sprite Kit,我正在尝试创建一个简单的动画(有3个纹理),每次玩家死亡时只运行一次。我通过在线查找如何更改纹理并使程序在更改纹理之间等待来编写下面的代码(我希望这样做,而不是使用atlas,因为它只有3个纹理) 游戏是有效的,因此球会停留在它死亡的位置。然后,当打印(我等待)打印3次时,它保持在该位置。然而,在等待之间,我的球的纹理没有改变。这是在下面的代码中唯一不起作用的东西 我如何才能使这段代码工作,或者有没有其他简单的方法来创建一次性动画 override func update(_ currentTi

我正在尝试创建一个简单的动画(有3个纹理),每次玩家死亡时只运行一次。我通过在线查找如何更改纹理并使程序在更改纹理之间等待来编写下面的代码(我希望这样做,而不是使用atlas,因为它只有3个纹理)

游戏是有效的,因此球会停留在它死亡的位置。然后,当打印(我等待)打印3次时,它保持在该位置。然而,在等待之间,我的球的纹理没有改变。这是在下面的代码中唯一不起作用的东西

我如何才能使这段代码工作,或者有没有其他简单的方法来创建一次性动画

override func update(_ currentTime: TimeInterval) {

    //CHECK IF BALL IS INSIDE THE MAP
    if (map_1_buffer.contains(ball.position)) {
           } else {
        let texture1 = SKTexture(imageNamed: "death_1")
        let texture2 = SKTexture(imageNamed: "death_2")
        let texture3 = SKTexture(imageNamed: "death_3")
        let normal = SKTexture(imageNamed: "Ball1")

        ball.texture = texture1
        sleep(UInt32(2))
        print("i waited 1")
        ball.texture = texture2
        sleep(UInt32(2))
        print("i waited 2")
        ball.texture = texture3
        sleep(UInt32(2))
        print("i waited 3")
        ball.texture = normal


        death += 1
        ball.physicsBody?.velocity.dx = 0
        ball.physicsBody?.velocity.dy = 0
        ball.position = CGPoint(x: -120, y: 40)

    }
}

update
函数旨在为每次显示刷新调用一次,因此将
sleep
调用之类的内容放入函数中并不能实现您想要的效果。我建议在这里阅读渲染周期概述:

渲染周期持续运行,您的目标是将内容放入
update
或物理处理例程中,如
didbegen
或诸如此类,以检测和响应游戏中发生的事情。响应包括调整节点属性、添加或删除节点或向节点添加操作等。在您的特定情况下,当检测到某个条件时,您似乎希望有一个动画。您可以在
update
中使用以下内容来完成此操作。它让球运行动画,当动作完成时,它将运行一些附加代码来重置球


func checkOutOfBounds(){
如果(!map_1_buffer.contains(ball.position)){
让texture1=SKTexture(图像名为:“death_1”)
让texture2=SKTexture(图像名为:“death_2”)
让texture3=SKTexture(图像名为:“death_3”)
让deathAnimation=SKAction.animate(使用:[texture1,texture2,texture3],timePerFrame:2.0)
球跑(脱乙烷){
自我死亡+=1
self.ball.texture=SKTexture(图像名为:“Ball1”)
self.ball.physicsBody?.velocity.dx=0
self.ball.physicsBody?.velocity.dy=0
self.ball.position=CGPoint(x:-120,y:40)
}
}
}
覆盖函数更新(uCurrentTime:TimeInterval){
签出边界()
}

(我没有实际测试此代码的框架,因此可能会出现打字错误,并且根据其范围,重置球的完成操作中的某些内容可能没有
self
,但想法很清楚。)

每次显示刷新都要调用
update
函数,因此,将
sleep
调用之类的东西放进去并不能满足您的需要。我建议在这里阅读渲染周期概述:

渲染周期持续运行,您的目标是将内容放入
update
或物理处理例程中,如
didbegen
或诸如此类,以检测和响应游戏中发生的事情。响应包括调整节点属性、添加或删除节点或向节点添加操作等。在您的特定情况下,当检测到某个条件时,您似乎希望有一个动画。您可以在
update
中使用以下内容来完成此操作。它让球运行动画,当动作完成时,它将运行一些附加代码来重置球


func checkOutOfBounds(){
如果(!map_1_buffer.contains(ball.position)){
让texture1=SKTexture(图像名为:“death_1”)
让texture2=SKTexture(图像名为:“death_2”)
让texture3=SKTexture(图像名为:“death_3”)
让deathAnimation=SKAction.animate(使用:[texture1,texture2,texture3],timePerFrame:2.0)
球跑(脱乙烷){
自我死亡+=1
self.ball.texture=SKTexture(图像名为:“Ball1”)
self.ball.physicsBody?.velocity.dx=0
self.ball.physicsBody?.velocity.dy=0
self.ball.position=CGPoint(x:-120,y:40)
}
}
}
覆盖函数更新(uCurrentTime:TimeInterval){
签出边界()
}

(我没有实际测试此代码的框架,因此可能会出现拼写错误,并且根据其范围,重置球的完成操作中的某些内容可能没有
self
,但想法很清楚。)

感谢bg2b的帮助;我的问题几乎解决了。我现在的代码等待动画执行,然后只转到resetBall函数一次(感谢您建议的二进制标志),因此死亡计数器工作

还有一个问题我一直在努力解决,我会把它作为一个新问题来问

func resetBall() {
    ballDying = false
    ball.physicsBody?.velocity.dx = 0
    ball.physicsBody?.velocity.dy = 0
    let normalTexture: SKTexture = SKTexture.init(imageNamed: "Ball1")
    self.ball.texture = SKTexture(imageNamed: "Ball1")
    self.ball.position = CGPoint(x: -120, y: 40)
    self.ball.size = CGSize(width: 40, height: 40)
    death += 1
    nbr_touches = 0
}

var ballDying = false

override func update(_ currentTime: TimeInterval) {
    if ((map_1_buffer.contains(ball.position)) == false) && !ballDying {
        ballDying = true
        let texture1 = SKTexture(imageNamed: "death_1")
        let texture2 = SKTexture(imageNamed: "death_2")
        let texture3 = SKTexture(imageNamed: "death_3")
        let deathAnimation = SKAction.animate(with: [texture1, texture2, texture3], timePerFrame: 0.03)
        ball.physicsBody?.velocity.dx = 0
        ball.physicsBody?.velocity.dy = 0
        self.ball.run(deathAnimation, completion: resetBall)
    }
}

感谢bg2b的帮助;我的问题几乎解决了。我现在的代码等待动画执行,然后只转到resetBall函数一次(感谢您建议的二进制标志),因此死亡计数器工作

还有一个问题我一直在努力解决,我会把它作为一个新问题来问

func resetBall() {
    ballDying = false
    ball.physicsBody?.velocity.dx = 0
    ball.physicsBody?.velocity.dy = 0
    let normalTexture: SKTexture = SKTexture.init(imageNamed: "Ball1")
    self.ball.texture = SKTexture(imageNamed: "Ball1")
    self.ball.position = CGPoint(x: -120, y: 40)
    self.ball.size = CGSize(width: 40, height: 40)
    death += 1
    nbr_touches = 0
}

var ballDying = false

override func update(_ currentTime: TimeInterval) {
    if ((map_1_buffer.contains(ball.position)) == false) && !ballDying {
        ballDying = true
        let texture1 = SKTexture(imageNamed: "death_1")
        let texture2 = SKTexture(imageNamed: "death_2")
        let texture3 = SKTexture(imageNamed: "death_3")
        let deathAnimation = SKAction.animate(with: [texture1, texture2, texture3], timePerFrame: 0.03)
        ball.physicsBody?.velocity.dx = 0
        ball.physicsBody?.velocity.dy = 0
        self.ball.run(deathAnimation, completion: resetBall)
    }
}

谢谢你的回复!实现您提供的动画的代码可以工作,但程序不会在执行resetBall函数之前等待整个动画。我编辑了我的问题,以反映我遇到的新问题。(我也试着把动画放在函数中,所以不是直接放在更新部分,但是结果是一样的)谢谢你的回复!实现您提供的动画的代码可以工作,但程序不会在执行resetBall函数之前等待整个动画。我编辑了我的问题,以反映我遇到的新问题。(我还尝试将动画放在函数中,因此不直接放在更新部分,但结果是相同的)我怀疑您现在可能遇到了一个问题,因为地图检查多次检测到球已死亡,并且球在更新循环中。可能会添加一个最初为false的标志,设置为