了解 Spritekit 运行 块,变量不符合预期

Understanding Spritekit run block, variable not as expected

我正在寻求一些帮助来理解为什么我的 speedToPoint 变量在执行 wait 操作时总是 1

这是我编写的 SKSpriteNode 扩展的一部分,用于让一只鸟飞到预定义矩形中的随机点。 speedToPoint 也在 1 和 4 之间随机分配,并用作 moveTo 动作的持续时间。但是,我还需要在操作序列中将 TimeInterval 用于我的等待块。

speedToPoint 确实在 运行 块中被随机化(我已经确认)。我如何在序列的下一部分的等待块中使用相同的随机数?

var speedToPoint:TimeInterval = 1

self.run(SKAction.repeatForever(
     SKAction.sequence([
        SKAction.run{
            speedToPoint = TimeInterval(Globals.sharedInstance.randomF(min: 1, max: 4))
            var pointX = Globals.sharedInstance.randomF(min: left,max: right)
            let pointY = Globals.sharedInstance.randomF(min: top,max:bottom)

        while abs(self.position.x.distance(to: pointX)) < 200 {
            pointX = Globals.sharedInstance.randomF(min: left,max: right)
        }

        self.xScale = pointX < self.position.x ? -1 : 1

        self.run(SKAction.move(to: CGPoint(x:pointX,y:pointY),duration: speedToPoint))
    },
    SKAction.wait(forDuration: speedToPoint)])
),withKey: "inFrame")

澄清一下,我真正想做的是让鸟儿飞到一个点,一旦它到达那个点,就飞到另一个点。我仍然在围绕动作序列以及它们是否真的等待完成继续前进。从我读过的内容来看,他们这样做了,但不是针对任何 move 操作。这就是 wait 在那里的原因。也许还有其他方法?

一个 SKAction,一旦创建,就不能修改,并且可以重复使用,例如。您不能修改持续时间参数,或更改其他传递的参数。这意味着如果您需要更改它,您必须重新创建它。当然,您可以更改现有动作的速度 属性,或者您可以暂停动作,但就修改现有动作而言,仅此而已。

要解决您的问题,您可以执行以下操作:

1) 创建一个将精灵移动到特定位置的动作

2) 操作完成后,您创建一个执行相同操作的新操作

您可以使用递归来完成此操作,就像这样(只需复制并粘贴代码以查看其工作原理):

import SpriteKit


class GameScene: SKScene, SKPhysicsContactDelegate {


    private var bird = SKSpriteNode(color: .purple, size: CGSize(width: 100, height: 100))

    override func didMove(to view: SKView) {

        addChild(bird)
        recursive()

    }

    func recursive(){

        let sequence = SKAction.sequence([

           SKAction.move(to: self.randomPoint(inRect: self.frame), duration: TimeInterval(self.random(between: 1, and: 3))),

            SKAction.run({[unowned self] in NSLog("Block executed"); self.recursive()})
            ])

        self.bird.run(sequence, withKey: "aKey")
    }

    func random(between minimum: CGFloat, and maximum: CGFloat) -> CGFloat{

    return CGFloat(arc4random()) / CGFloat(UINT32_MAX) * abs(minimum - maximum) + min(minimum, maximum)
}

    func randomPoint(inRect rect:CGRect)->CGPoint{


        let x = random( between: -rect.size.width / 2.0 , and: rect.origin.x + rect.size.width/2.0)
        let y = random(between: -rect.size.height / 2.0 , and: rect.origin.y + rect.size.height/2.0)

        return CGPoint(x: x, y: y)


    }

}

要停止此操作,请删除与其关联的密钥。