for 循环不按顺序执行代码 (swift + spritekit)
for loop not executing code sequencially (swift + spritekit)
这是我的代码:
override func didMoveToView(view: SKView) {
/* Setup your scene here */
let origin = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame))
let delay = SKAction.waitForDuration(2.0)
for (var i = 0; i < 6; i++) {
//generate a random point on a circle centered at origin with radius of 500
let point = randomPointOnCircle(500, center: origin)
let chanceToSpawn = arc4random_uniform(100)
switch chanceToSpawn {
case 0...60:
self.runAction(delay){
let smallBall = SKSpriteNode(imageNamed: "smallBall”)
self.addChild(smallBall)
smallBall.xScale = 0.05
smallBall.yScale = 0.05
smallBall.position = point
let finalDest = CGPointMake(origin.x, origin.y)
let moveAction = SKAction.moveTo(finalDest, duration: 5.0)
smallBall.runAction(SKAction.sequence([SKAction.waitForDuration(0.1), moveAction, SKAction.runBlock({
smallBall.removeFromParent()
})]))
delay
}
break
case 61...80:
//same as case 0…60, smallBall changed to “mediumBall”
break
case 81...99:
//same as case 0…60, smallBall changed to “largeBall”
break
default:
break
} // ends switch statement
}//ends for loop
}//end didMoveToView
基本上,我的球会在圆上的随机点上生成并向中心移动。但我遇到的问题是,无论我如何重新安排事物(或重写事物,即尝试不同的循环或定义用于生成球和球运动的函数并简单地从 switch 语句内部调用它们)所有球同时产生。我正在努力让它们一个接一个地产生(意味着一个球产生,线程等待几秒钟,然后产生另一个球。),我似乎无法弄清楚为什么每个球都同时产生时间和所有其他球一样。
我是 Swift/Spritekit 编程的新手,我觉得我忽略了一些小细节,这让我很烦恼。任何帮助表示赞赏!
试试这个,可能是因为你同时为每个球添加动作,
smallBall.runAction(SKAction.sequence([SKAction.waitForDuration(0.1 + (i * 0.35/2)), moveAction, SKAction.runBlock({
smallBall.removeFromParent()
})])) // delay added (0.1 + (increment the daly))
试试这个
for 循环的执行速度比您想象的要快!您的 for 循环可能会立即执行。
"Why is that? I have already called self.runAction(delay)
to delay the for loop!" 你问了。不幸的是,延迟操作实际上并没有延迟 for 循环。它只会延迟您 运行 在 self
上的其他操作。
要解决此问题,请尝试延迟不同的数量,具体取决于 for 循环计数器:
self.runAction(SKAction.waitForDuration(i * 2 + 2)) { ... }
这样,球每两秒就会出现一次。
您的问题是您在 for 循环的每次迭代中调用 运行Action。这意味着您的所有操作将 运行 同时进行。
您要做的是创建一系列操作。然后在 for 循环之后,运行 一系列操作。
(注意:我冒昧清理了你的代码)
override func didMoveToView(view: SKView) {
/* Setup your scene here */
let origin = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame))
let delay = SKAction.waitForDuration(2.0)
var sequence = [SKAction]()
for (var i = 0; i < 6; i++) {
//generate a random point on a circle centered at origin with radius of 500
let point = randomPointOnCircle(500, center: origin)
let chanceToSpawn = arc4random_uniform(100)
var ballname = "smallBall”
switch chanceToSpawn {
case 61...80:
//same as case 0…60, smallBall changed to “mediumBall”
ballname = "mediumBall”
case 81...99:
//same as case 0…60, smallBall changed to “largeBall”
ballname = "largeBall”
default: ()
} // ends switch statement
sequence.append(delay)
sequence.append(
SKAction.run()
{
[unowned self] in
let ball = SKSpriteNode(imageNamed: ballName)
self.addChild(ball)
ball.xScale = 0.05
ball.yScale = 0.05
ball.position = point
let finalDest = CGPointMake(origin.x, origin.y)
let moveAction = SKAction.moveTo(finalDest, duration: 5.0)
let briefWait = SKAction.waitForDuration(0.1)
let remove = SKAction.removeFromParent()
let moveSeq = SKAction.sequence([briefWait ,moveAction,remove])
ball.runAction(moveSeq)
}
)
}//ends for loop
self.run(SKAction.sequence(sequence))
}//end didMoveToView
这是我的代码:
override func didMoveToView(view: SKView) {
/* Setup your scene here */
let origin = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame))
let delay = SKAction.waitForDuration(2.0)
for (var i = 0; i < 6; i++) {
//generate a random point on a circle centered at origin with radius of 500
let point = randomPointOnCircle(500, center: origin)
let chanceToSpawn = arc4random_uniform(100)
switch chanceToSpawn {
case 0...60:
self.runAction(delay){
let smallBall = SKSpriteNode(imageNamed: "smallBall”)
self.addChild(smallBall)
smallBall.xScale = 0.05
smallBall.yScale = 0.05
smallBall.position = point
let finalDest = CGPointMake(origin.x, origin.y)
let moveAction = SKAction.moveTo(finalDest, duration: 5.0)
smallBall.runAction(SKAction.sequence([SKAction.waitForDuration(0.1), moveAction, SKAction.runBlock({
smallBall.removeFromParent()
})]))
delay
}
break
case 61...80:
//same as case 0…60, smallBall changed to “mediumBall”
break
case 81...99:
//same as case 0…60, smallBall changed to “largeBall”
break
default:
break
} // ends switch statement
}//ends for loop
}//end didMoveToView
基本上,我的球会在圆上的随机点上生成并向中心移动。但我遇到的问题是,无论我如何重新安排事物(或重写事物,即尝试不同的循环或定义用于生成球和球运动的函数并简单地从 switch 语句内部调用它们)所有球同时产生。我正在努力让它们一个接一个地产生(意味着一个球产生,线程等待几秒钟,然后产生另一个球。),我似乎无法弄清楚为什么每个球都同时产生时间和所有其他球一样。
我是 Swift/Spritekit 编程的新手,我觉得我忽略了一些小细节,这让我很烦恼。任何帮助表示赞赏!
试试这个,可能是因为你同时为每个球添加动作,
smallBall.runAction(SKAction.sequence([SKAction.waitForDuration(0.1 + (i * 0.35/2)), moveAction, SKAction.runBlock({
smallBall.removeFromParent()
})])) // delay added (0.1 + (increment the daly))
试试这个
for 循环的执行速度比您想象的要快!您的 for 循环可能会立即执行。
"Why is that? I have already called self.runAction(delay)
to delay the for loop!" 你问了。不幸的是,延迟操作实际上并没有延迟 for 循环。它只会延迟您 运行 在 self
上的其他操作。
要解决此问题,请尝试延迟不同的数量,具体取决于 for 循环计数器:
self.runAction(SKAction.waitForDuration(i * 2 + 2)) { ... }
这样,球每两秒就会出现一次。
您的问题是您在 for 循环的每次迭代中调用 运行Action。这意味着您的所有操作将 运行 同时进行。
您要做的是创建一系列操作。然后在 for 循环之后,运行 一系列操作。
(注意:我冒昧清理了你的代码)
override func didMoveToView(view: SKView) {
/* Setup your scene here */
let origin = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame))
let delay = SKAction.waitForDuration(2.0)
var sequence = [SKAction]()
for (var i = 0; i < 6; i++) {
//generate a random point on a circle centered at origin with radius of 500
let point = randomPointOnCircle(500, center: origin)
let chanceToSpawn = arc4random_uniform(100)
var ballname = "smallBall”
switch chanceToSpawn {
case 61...80:
//same as case 0…60, smallBall changed to “mediumBall”
ballname = "mediumBall”
case 81...99:
//same as case 0…60, smallBall changed to “largeBall”
ballname = "largeBall”
default: ()
} // ends switch statement
sequence.append(delay)
sequence.append(
SKAction.run()
{
[unowned self] in
let ball = SKSpriteNode(imageNamed: ballName)
self.addChild(ball)
ball.xScale = 0.05
ball.yScale = 0.05
ball.position = point
let finalDest = CGPointMake(origin.x, origin.y)
let moveAction = SKAction.moveTo(finalDest, duration: 5.0)
let briefWait = SKAction.waitForDuration(0.1)
let remove = SKAction.removeFromParent()
let moveSeq = SKAction.sequence([briefWait ,moveAction,remove])
ball.runAction(moveSeq)
}
)
}//ends for loop
self.run(SKAction.sequence(sequence))
}//end didMoveToView