完成在SpriteNode上运行的操作,而不禁用触摸

时间:2017-04-10 21:31:11

标签: ios swift sprite-kit nodes skaction

我有一个物理身体被分成部分(躯干,腿部,头部等)的玩家,现在我在屏幕上有一个控制玩家运动的按钮,如果按下按钮向右移动玩家移动到权利,那部分工作正常。问题是每次运动改变时调用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
        }
    }
}

2 个答案:

答案 0 :(得分:0)

我能够解决这个问题,但是我仍然确定有一个更好的方法,所以如果你知道它肯定会告诉你。这是我做的: 首先,我添加了一个名为isWalking的布尔值,以了解步行动画是打开(true)还是关闭(false)并将其设置为false。然后我添加if语句只在​​动画关闭(false)时调用walk()并将boolean设置为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()以使用完成块并将布尔值再次设置为关闭(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
        })
    }
}

答案 1 :(得分:0)

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

关于您的问题,您可以使用hasAction来确定您的SKNode当前是否正在执行任何操作,并且您可以使用关键机制进行更好的操作管理。

参见下一个Q& A checking if an SKNode is running a SKAction