【问题标题】:Finish action running on a SpriteNode without disabling touches在不禁用触摸的情况下完成在 SpriteNode 上运行的操作
【发布时间】:2017-09-06 02:08:33
【问题描述】:

我有一个玩家,他的物理身体被分成几部分(躯干、腿、头等),现在我在屏幕上有一个按钮来控制玩家的移动,如果按钮被向右按下,玩家就会移动到正确的,那部分工作正常。问题是每次运动发生变化时都会调用 walk() 方法,它所做的是让玩家的腿看起来像走路一样,但是如果运动没有停止,那么会在没有完成的情况下继续调用 walk()动画,所以它看起来像是来回卡住了。我想要实现的是让玩家能够不断地行走,但要调用一次 walk() (动画方法),完成,然后再次调用(只要仍然按下行走按钮)。这是我到目前为止所拥有的:

func walk(){
    let leftFootWalk = SKAction.run {
        let action = SKAction.moveBy(x: 1, y: 0.1, duration: 0.1)
        let actionReversed = action.reversed()
        let seq = SKAction.sequence([action, actionReversed])
        self.leftUpperLeg.run(seq)
        self.leftLowerLeg.run(seq)
    }

    let rightFootWalk = SKAction.run {
        let action = SKAction.moveBy(x: 0.4, y: 0.1, duration: 0.1)
        let actionReversed = action.reversed()
        let seq = SKAction.sequence([action, actionReversed])
        self.rightUpperLeg.run(seq)
        self.rightLowerLeg.run(seq)
    }

    let group = SKAction.sequence([leftFootWalk, SKAction.wait(forDuration: 0.2), rightFootWalk])

    run(group)
}


extension GameScene: InputControlProtocol {
func directionChangedWithMagnitude(position: CGPoint) {
    if isPaused {
        return
    }

    if let fighter = self.childNode(withName: "fighter") as? SKSpriteNode, let fighterPhysicsBody = fighter.physicsBody {

        fighterPhysicsBody.velocity.dx = position.x * CGFloat(300)
        walk()

        if position.y > 0{
            fighterPhysicsBody.applyImpulse(CGVector(dx: position.x * CGFloat(1200),dy: position.y * CGFloat(1200)))
        }else{
            print("DUCK") //TODO: duck animation
        }
    }
}

【问题讨论】:

    标签: ios swift sprite-kit nodes skaction


    【解决方案1】:

    首先你可以使用SKAction.runBlock({ self.doSomething() }) 作为动作序列中的最后一个动作,而不是使用完成。

    关于你的问题,你可以使用hasAction来判断你的SKNode当前是否正在运行任何action,你可以使用key机制更好的进行action管理。

    查看下一个问答 checking if an SKNode is running a SKAction

    【讨论】:

      【解决方案2】:

      我能够解决这个问题,但是我仍然确信那里有更好的方法,所以如果你知道它一定要告诉。这是我所做的: 首先,我添加了一个名为 isWalking 的布尔值,以了解行走动画是打开(true)还是关闭(false),并将其设置为 false。然后我添加了 if 语句来调用 walk() 仅当动画关闭(false)并将布尔值设置为 on(true)。

      func directionChangedWithMagnitude(position: CGPoint) {
          if isPaused {
              return
          }
      
          if let fighter = self.childNode(withName: "fighter") as? SKSpriteNode, let fighterPhysicsBody = fighter.physicsBody {
      
              fighterPhysicsBody.velocity.dx = position.x * CGFloat(300)
              print(fighterPhysicsBody.velocity.dx)
      
              if !isWalking{
                  isWalking = true
                  walk()
              }
          }
      }
      

      我将 walk() 更改为使用完成块并将布尔值再次设置为 off(false)

      func walk(){
          let walkAction = SKAction.moveBy(x: 5, y: 5, duration: 0.05)
          let walk = SKAction.sequence([walkAction, walkAction.reversed()])
      
          leftUpperLeg.run(walk) {
              self.rightUpperLeg.run(walk)
          }
      
          leftLowerLeg.run(walk) { 
              self.rightLowerLeg.run(walk, completion: { 
                  self.isWalking = false
              })
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-29
        • 1970-01-01
        • 2014-12-14
        • 1970-01-01
        相关资源
        最近更新 更多