2016-03-21 4 views
0

Я делаю небольшую игру: у меня есть матрица для SKSpriteNode и чисел, когда игра заканчивается. Я пытаюсь сделать анимацию, я просматриваю матрицу, меняя только спрайт один за другим, следуя порядку цифры. Посмотрите Board (квадраты находятся в Sknode и числа в других Sknode)Как анимировать матрицу, меняющую спрайты один за другим?

Идея это изменить спрайт другого цвета и подождать 2 секунды после изменения на следующий, но я не могу это сделать. Я не знаю, как сменить спрайт один за другим. Я делаю эту функцию «RecoverMatrix()», это изменение спрайтов, но все сразу, это как бы не ожидание, он меняет все спрайты и дождитесь 2 секунд.

func RecoverMatrix() {       

    var cont = 1 
    TileLayer.removeAllChildren() 
    numLayer.removeAllChildren() 
    let imageEnd = SKAction.setTexture(SKTexture(imageNamed: "rectangle-play")) 
    let waiting = SKAction.waitForDuration(2) 

    var scene: [SKAction] = [] 
    var tiles: [SKSpriteNode] = [] 

    while cont <= 16 { 

     for var column = 0; column < 4; column++ { 
      for var row = 0; row < 4; row++ { 

       if matrix[column][row].number == cont { 

        let label = SKLabelNode() 
        label.text = "\(matrix[column][row])" 
        label.fontSize = TileHeight - 10 
        label.position = pointForBoard(column, row: row) 
        label.fontColor = UIColor.whiteColor() 

        let tile = SKSpriteNode() 
        tile.size = CGSize(width: TileWidth - 3, height: TileHeight - 3) 
        tile.position = pointForBoard(column, row: row, _a: 0) 
        TileLayer.addChild(tile) 
        numLayer.addChild(label) 

        tiles.append(tile) 

        scene.append(SKAction.sequence([imageEnd, waiting])) 

        tile.runAction(imageEnd) 
        runAction(waiting) 
        didEvaluateActions() 
       } 
      } 
     } 
     cont++ 
    } 

    for tile in tiles { 
     tile.runAction(SKAction.sequence(scene)) 
     self.runAction(SKAction.waitForDuration(1)) 
    } 
} 

Итак, мне нужна помощь, я не нахожу способ сделать эту анимацию. Я очень ценю помощь. Благодаря!

+0

Это, безусловно, выполнимо, если я вас хорошо понимаю ... Не пристально посмотрел ваш код, но я предполагаю, что у вас уже есть массив спрайтов с сохраненным порядком. То, что вам нужно сделать, - это перебрать все из них (например, внутри цикла for) и запустить последовательность действий для каждой плитки (спрайт), которую вы хотите изменить. Последовательность действий должна состоять в основном из двух частей. Первая часть будет 'SKAction.waitForDuration()', и это должно измениться для каждого фрагмента. Вторая часть - это фактическое изменение цвета или все, что вы планируете. Итак, просто рассчитайте действие ожидания соответствующим образом, и вы получите эффект, который вы хотите. – Whirlwind

+0

Так что вам просто нужно увеличить продолжительность ожидания для каждого узла. Кроме того, вы должны, вероятно, запустить эту последовательность на каждом узле отдельно, а не на сцене. И что такое 'didEvaluateActions()' вызов внутри вашего цикла while? Это выглядит теневым :) Вы не должны называть этот метод [напрямую] (https://developer.apple.com/library/tvos/documentation/SpriteKit/Reference/SKScene_Ref/index.html#//apple_ref/occ/instm/SKScene/didEvaluateActions) ... – Whirlwind

ответ

2

Это, как вы можете запустить действие на каждом узле, в то же время (используя цикл для перебора всех плиток):

class GameScene: BaseScene, SKPhysicsContactDelegate { 
    var blocks: [[SKSpriteNode]] = [] 

    override func didMoveToView(view: SKView) { 
    makeBoard(4, height: 4) 

    colorize() 
    } 

    func makeBoard(width:Int, height:Int) { 
    let distance:CGFloat = 50.0 

    var blockID = 1 

    //make a width x height matrix of SKSpriteNodes 
    for j in 0..<height { 
     var row = [SKSpriteNode]() 

     for i in 0..<width { 
     let node = SKSpriteNode(color: .purpleColor(), size: CGSize(width: 30, height: 30)) 
     node.name = "\(blockID++)" 

     if let nodeName = node.name {node.addChild(getLabel(withText: nodeName))} 
     else { 
      //handle error 
     } 

     node.position = CGPoint(x: frame.midX + CGFloat(i) * distance, 
      y: frame.midY - CGFloat(j) * distance) 

     row.append(node) 

     addChild(node) 
     } 

     blocks.append(row) 
    } 
    } 

    func colorize() { 
    let colorize = SKAction.colorizeWithColor(.blackColor(), colorBlendFactor: 0, duration: 0.5) 
    var counter = 0.0 
    let duration = colorize.duration 

    for row in blocks { 
     for sprite in row { 
     counter++ 

     let duration = counter * duration 
     let wait = SKAction.waitForDuration(duration) 

     sprite.runAction(SKAction.sequence([wait, colorize])) 
     } 
    } 
    } 

    func getLabel(withText text:String) -> SKLabelNode { 
    let label = SKLabelNode(fontNamed: "ArialMT") 
    label.fontColor = .whiteColor() 
    label.text = text 
    label.fontSize = 20 
    label.horizontalAlignmentMode = .Center 
    label.verticalAlignmentMode = .Center 

    return label 
    } 
} 

И результат:

enter image description here

Так, в основном, как я уже сказал в комментариях, вы можете запускать все действия в тот же момент, это примерно то, когда начнется каждое действие.

+0

Как я могу сделать, если анимация выше другого узла, который не является основным? – AnaMM

+0

@AnaMM Не уверен, что вы просите ... – Whirlwind

+0

Извините, что когда-нибудь его трудно объяснить, я попробую еще раз. У меня есть {let tileLayer = SKNode()} Его в том узле, где добавлены поля. Я имею в виду, когда я добавляю что-то на сцену вместо того, чтобы делать {addchild (square)}, я делаю {tileLayer.addchild (square)}. Поэтому, когда я меняю цвет, действие не работает :( – AnaMM

0

Вы, кажется, воображаете, что runAction(waiting) означает, что вы code паузы и ожидания, пауза между петлями. Это не так (и на самом деле нет способа сделать это). Ваш код проходит через все петли, сейчас, KABOOM, сразу.

Таким образом, все действия настраиваются немедленно и выполняются вместе.