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