了解 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)
}
}
要停止此操作,请删除与其关联的密钥。
我正在寻求一些帮助来理解为什么我的 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)
}
}
要停止此操作,请删除与其关联的密钥。