【问题标题】:How to trigger a function when spriteSceneNode reach at a point in ios SpriteKit当spriteSceneNode到达ios SpriteKit中的某个点时如何触发函数
【发布时间】:2017-12-03 04:26:17
【问题描述】:

我有一个 spritekit 场景,并向其中一个 spriteSceneNode 添加了一些动作序列。 比如说,一个名为 node1 的 spriteSceneNode 移动到 point1 然后它会移动到 point2 然后 point3 等等。它是通过使用“SKAction.moveTo”函数实现的。

我的问题是,

是否可以在到达每个点(point1或point2或point3)时调用自定义函数?

在这里添加一些代码。

 func MoveObjectToAnotherPosition(arrayOfPoints : [CGPoint],object: SKSpriteNode   )  {
    let from   = object.position


    var curPoint1 = object.position


    let move = SKAction.move(to: from ,duration: 0.5)
    var arrayOfMove : [SKAction] = []
    arrayOfMove.append(move)
    for point in (arrayOfPoints ) {
        let move2 = SKAction.move(to: point,duration: 2.5)

       let deltaX = point.x - curPoint1.x
        let deltaY = point.y - curPoint1.y
        let angle = atan2(deltaY, deltaX)
        // let graph =  childNode(withName: "Graph1")?
        print(angle)
        let ang = point.angle(to: curPoint1)
        print(ang)
        let codeToRunWhenReachingPointX = SKAction.run {
            let anglevalue = angle + 90 * self.DegreesToRadians
            self.movObject.zPosition = anglevalue
            print(anglevalue)
        }


        //print(anglevalue)
        let rotate = SKAction.rotate(byAngle: -angle, duration: 0.0)
        arrayOfMove.append(codeToRunWhenReachingPointX)
        arrayOfMove.append(move2)
        curPoint1 = point
    }


    let moveToSequence = SKAction.sequence(arrayOfMove)

    object.run(moveToSequence)
}

有什么帮助吗?

【问题讨论】:

    标签: ios swift3 sprite-kit skaction


    【解决方案1】:

    是的,您可以在 SKAction 完成时调用任何代码。为此,您可以使用 run(_:) 创建一个运行任何代码的 SKAction。

    由于您想在到达 X 点时调用一些代码,所以我会为每个 X 点添加类似的内容:

    let moveToPointX = SKAction.move(to: pointX, duration: someDuration)
    arrayOfMove.append(moveToPointX)
    
    let codeToRunWhenReachingPointX = SKAction.run {
         // add whatever code you need, e.g. a closure passed to this function
    }
    arrayOfMove.append(codeToRunWhenReachingPointX)
    

    然后你可以通过调用来运行你现在的动作序列

    let moveToSequence = SKAction.sequence(arrayOfMove)
    object.run(moveToSequence)
    

    值得注意的是,运行动作序列不会等待codeToRunWhenReachingPointX 完成后才移动到下一个点。假设您有 SKActions [m1, c1, m2, c2] 数组,其中 m 是您的移动操作,而 c 是您的“运行代码”操作。当您运行这个序列时,会发生这种情况:m1 将运行,当它完成时 c1 将运行,然后不等待 c1 完成,m2 将运行,当 m2 完成时 c2 将运行。

    还可以查看run(_:completion:) 方法,它的工作原理类似。

    希望这会有所帮助!

    【讨论】:

    • “值得注意的是,运行动作序列不会等待 codeToRunWhenReachingPointX 完成”是什么意思?该块在 1 帧内全部执行,除非您将其扔到不同的线程上。如果阻止尚未完成,您的应用应该锁定并滞后
    • 我可能错了,但是在那个块中放一个大函数来执行(或者一个调用其他函数的函数,做其他动画等)。在“大功能”完成之前,您将看到节点开始移动到第二个点。至少这是我在简单的 spritekit 项目中看到的。也许我错了。有没有更好的办法?
    • @JohnV 我使用 SKAction.run 进行了更改,但我的 skSpritenode 对象 zposition 未更新,但该函数已正确触发
    • @Araf 我必须承认我有点迷失在这里......代码是否正确,您更改了 movObject 的 zposition,但是您在对象上运行了 SKActions 序列?
    • @Araf 作为旁注,当您在闭包中捕获 self 时,就像您在 SKAction.run {... 中所做的那样,添加“[unowned self] in”(没有“)就在闭包中的代码之前,例如:SKAction.run { [unowned self] in // 然后是代码的其余部分。否则,您会创建对 self 的强引用,它可能会弄乱 ARC 并导致内存泄漏。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多