【问题标题】:Simple animation with textures not executing in SpriteKit在 SpriteKit 中没有执行纹理的简单动画
【发布时间】:2020-02-29 13:11:30
【问题描述】:

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

游戏正常运行,因此球会停留在它死亡的位置。然后它停留在那个位置,而 print(I waited) 打印 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)

    }
}

【问题讨论】:

  • 我怀疑您现在可能会遇到问题,因为地图检查在更新循环中多次检测到球为死球。也许添加一个标志ballDying,它最初是false,当你即将运行动画时将它设置为true,用&& !ballDying检查map1_buffer.contains,并让resetBall再次清除标志。
  • @bg2b 感谢您花时间帮助我!我添加了标志,使程序只运行一次 resetBall 函数。我遇到的最后一个问题是在其余函数中更改纹理的行没有执行。我发布了一个关于这个问题的答案更多
  • 在 bg2b 给出以下答案后,此问题被大幅修改为新问题,使他们的答案无效。我们在这里不这样做。原因是 Stack Overflow 是一组精选的问答集,我们希望未来的读者能够从这些材料中学习;如果可能对问题进行编辑,使给定的答案不再有意义,我们就会剥夺读者学习某些东西的机会。
  • 一般来说,作为问题作者,如果为您提供的解决方案提示了一个新问题,那么请考虑提出一个新问题。有时可以为现有问题添加附录(只要附加问题密切相关),但在大多数情况下,最好提出一个新问题。可以将新问题链接到旧问题以提供上下文。可以像您所做的那样自行回答,但不能发布问题 - 答案空间仅用于回答。
  • @halfer 好的!谢谢你的澄清

标签: swift xcode sprite-kit


【解决方案1】:

update 函数旨在为每次显示刷新调用一次,因此将诸如 sleep 调用之类的东西放入其中不会达到您想要的效果。我建议在这里阅读渲染周期的概述:https://developer.apple.com/documentation/spritekit/skscene/responding_to_frame-cycle_events

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


func checkOutOfBounds() {
  if (!map_1_buffer.contains(ball.position)) {
    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: 2.0)
    ball.run(deathAnimation) {
      self.death += 1
      self.ball.texture = SKTexture(imageNamed: "Ball1")
      self.ball.physicsBody?.velocity.dx = 0
      self.ball.physicsBody?.velocity.dy = 0
      self.ball.position = CGPoint(x: -120, y: 40)
    }
  }
}

override func update(_ currentTime: TimeInterval) {
  checkOutOfBounds()
}

(我没有实际测试此代码的框架,因此可能存在拼写错误,并且重置球的完成操作中的某些内容可能没有self,具体取决于其范围,但想法是希望清楚。)

【讨论】:

  • 感谢您的回复!实现您提供的动画的代码有效,但程序在执行 resetBall 函数之前不会等待整个动画。我编辑了我的问题以反映我遇到的新问题。 (我也试过把动画放在一个函数里,所以不是直接放在更新部分,但结果是一样的)
【解决方案2】:

感谢 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)
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-10
    相关资源
    最近更新 更多