我创建了一个场景3D迷宫世界,玩家可以在其中移动。跳跃之类的一些动作包括上下移动相机,同时在几秒钟的一段时间内更改以查看方向。在此期间
我可以创建一个符合跳跃持续时间并设置一个布尔的计时器,但我希望有一种更简单的方法来检查相机的scnnode。
是否有一种简单的方法来查看相机的scnnode是否不再运行跳跃的scnaction,以便我可以在其他点击和滑动操作前添加此逻辑?
或也许有一个可以设置我可以在跳跃序列开始和结束时放置的布尔?
这是我的跳跃代码:
let jumpUp: SCNAction = SCNAction.move(to: SCNVector3Make(Float(Int(-yPos)), Float(Int(xPos)), jumpHeight), duration: jumpTime)
let jumpAppex: SCNAction = SCNAction.wait(duration: jumpWaitTime)
let fallDown: SCNAction = SCNAction.move(to: SCNVector3Make(Float(Int(-yPos)), Float(Int(xPos)), cameraHeight), duration: jumpTime)
var lookDown: SCNAction = SCNAction.rotateTo(x: 0, y: 0, z: CGFloat(π), duration: jumpTurnTime)
let noLook: SCNAction = SCNAction.wait(duration: jumpTime*2.0)
var lookBack: SCNAction = SCNAction.rotateTo(x: 0, y: 0, z: 0, duration: jumpTurnTime)
switch playerDirection.direction
{
case .south:
lookDown = SCNAction.rotateTo(x: 0, y: 0, z: CGFloat(southZ), duration: jumpTurnTime)
lookBack = SCNAction.rotateTo(x: CGFloat(π/2), y: 0, z: CGFloat(southZ), duration: jumpTurnTime)
case .north:
lookDown = SCNAction.rotateTo(x: 0, y: 0, z: CGFloat(northZ), duration: jumpTurnTime)
lookBack = SCNAction.rotateTo(x: CGFloat(π/2), y: 0, z: CGFloat(northZ), duration: jumpTurnTime)
case .east:
lookDown = SCNAction.rotateTo(x: 0, y: 0, z: CGFloat(eastZ), duration: jumpTurnTime)
lookBack = SCNAction.rotateTo(x: CGFloat(π/2), y: 0, z: CGFloat(eastZ), duration: jumpTurnTime)
case .west:
lookDown = SCNAction.rotateTo(x: 0, y: 0, z: CGFloat(westZ), duration: jumpTurnTime)
lookBack = SCNAction.rotateTo(x: CGFloat(π/2), y: 0, z: CGFloat(westZ), duration: jumpTurnTime)
}
let sequenceJump = SCNAction.sequence([jumpUp, jumpAppex, fallDown])
let sequenceLook = SCNAction.sequence([lookDown, noLook, lookBack])
mazeScene.mazeCamera.runAction(sequenceJump)
mazeScene.mazeCamera.runAction(sequenceLook)
谢谢
格雷格
动作很奇怪。
这个想法受到了COCOS2D的重大启发(基本上是1:1映射和``盗窃''),在那里它们被用作避免直接与游戏环,状态和时间(某种)直接互动的一种方式。动作为处理时间和活动的创造和援引提供了一种模块化和抽象,以及对结论的非常原始的处理。
您可以看到在阅读此处阅读时的SpriteKit和Scenekit的动作与原始想法的相似之处:http://python.cocos2d.org/doc/programming_guide/actions.html
由于其创造的分歧和不断发展的本质,有人忘了让他们意识到自己的状态,尽管他们影响了节点状态的某些方面。动作对象具有"跑步"状态几乎是很有意义的。但是,据我所知,他们不是。
相反,您可以检查节点是否具有给定的操作,如果这样做,则可以推断该动作正在运行。
尽管大多数动作在多长时间内都在做一些事情,但您也无法查询他们在持续时间内的距离,或者他们刚刚发射的价值观或接下来会发送的价值观。但是,有些动作是为了应对所有动作所缺少的事实,这意味着如果您愿意,您需要使用提供此功能的特殊动作。
以及本来应该是天生的设施的这种递归性是从熟悉时间表和关键帧的人的角度思考的最令人讨厌的一部分。
整体上,总而言之:您无法查询动作的状态,其进度,或者它刚刚或将要使用的价值。这绝对是荒谬的。
我不知道这在各种动作的演变中如何被忽略了……它们是时间管理和模块化活动创造者。在其中包括状态和进度报告似乎是如此合乎逻辑,以至于...好吧,我不知道……只是他们不奇怪。
所以,回答您的问题:
您可以使用完成处理程序,这是在操作完成时调用某些代码的,以设置值或调用其他功能或清理内容,或者您想要的任何东西。
序列操作,在scnaction。当您需要时,按动作顺序。如果对当前的行动具有时间和属性的值有透明度,则可以避免所有这些...但是...
您还可以使用一些特殊的动作,这些操作通过对其进行的更改而对其编辑的价值有所了解。我只熟悉SkeaseKit中的浮动设置功能,但是您可以在Scenekit和SpriteKit中这样做(如果您是我的编码器要好得多)。Skeasekit隐藏了几个超级有用的价值的动作。
我使用它,例如,这样的杂物在持续时间(时间),在这种情况下以线性方式更改0到1的值,并且每个帧(希望)更新节点的.xscale这种成长是运行的:
let growAction = SKEase.createFloatTween(
start: 0,
ender: 1,
timer: time,
easer: SKEase.getEaseFunction(.curveTypeLinear,
easeType: .easeTypeOut),
setterBlock: {(node, i) in
node.xScale = i}
)
我最终使用.customation:
我添加了一个类变量iSHumping
然后在功能代码的前面我添加:
isJumping = true
并添加了scnaction:
let jumpDone: SCNAction = SCNAction.customAction(duration: 0, action: {_,_ in self.isJumping = false})
然后将序列更改为:
let sequenceLook = SCNAction.sequence([lookDown, noLook, lookBack, jumpDone])
然后,我只是在iShinging上做一个,看看跳跃运动是否已经完成。
有一个runAction(_:completionHandler:)
,您可以在其中处理完成。请参阅文档。
因此,您可以通过完成块并在此处检查必要的条件:
mazeScene.mazeCamera.runAction(sequenceJump) {
print("Sequence jump is completed")
}