для цикла, не выполняющего код последовательно (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, и мне кажется, что я упускаю какую-то маленькую деталь, и это действительно беспокоит меня. Любая помощь ценится!
3 ответа:
Ибо циклы выполняются быстрее, чем вы думаете! Ваш цикл for, вероятно, выполняется мгновенно.
" Почему это? Я уже вызвал
self.runAction(delay)
, чтобы задержать цикл for!- ты сам спросил. Ну, действие задержки на самом деле не задерживает цикл for, к сожалению. Это просто задерживает другие действия, которые вы выполняетеself
.Чтобы исправить это, попробуйте задержать различные суммы, зависящие от счетчика цикла for:
Таким образом, шары будут появляться каждые две секунды.self.runAction(SKAction.waitForDuration(i * 2 + 2)) { ... }
Попробуйте это, может быть из-за того же времени, когда вы добавляете действия для каждого шара,
smallBall.runAction(SKAction.sequence([SKAction.waitForDuration(0.1 + (i * 0.35/2)), moveAction, SKAction.runBlock({ smallBall.removeFromParent() })])) // delay added (0.1 + (increment the daly))
Попробуйте это
Ваша проблема заключается в том, что вы вызываете runAction на каждой итерации цикла for. Это означает, что все ваши действия будут выполняться одновременно.
То, что вы хотите сделать, - это создать массив действий. затем после цикла 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