для цикла, не выполняющего код последовательно (swift spritekit)

#swift #for-loop #sprite-kit #switch-statement #spawning

#swift #для цикла #sprite-kit #оператор переключения #порождение

Вопрос:

Вот мой код:

 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, и мне кажется, что я упускаю из виду некоторые мелкие детали, и это действительно беспокоит меня. Любая помощь приветствуется!

Ответ №1:

Циклы For выполняются быстрее, чем вы думаете! Ваш цикл for, вероятно, выполняется мгновенно.

«Почему это? Я уже звонил self.runAction(delay) , чтобы отложить цикл for!» вы спросили. К сожалению, действие задержки на самом деле не задерживает цикл for. Это просто задерживает другие действия, которые вы выполняете self .

Чтобы исправить это, попробуйте отложить разные суммы, в зависимости от счетчика цикла for:

 self.runAction(SKAction.waitForDuration(i * 2   2)) { ... }
  

Таким образом, шары будут появляться каждые две секунды.

Комментарии:

1. Это сработало! Большое вам спасибо! Единственная проблема, с которой я столкнулся, заключалась в том, что мне пришлось явно объявить, что переменная i была двойной, но в остальном все работает хорошо! Еще раз спасибо! : D

Ответ №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))
  

попробуйте это

Ответ №3:

Ваша проблема в том, что вы вызываете 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