Поменяйте местами два узла SKSpriteNode и дождитесь завершения - PullRequest
0 голосов
/ 02 апреля 2020

У меня есть функция, которая должна поменять местами два SKSpriteNodes (карта является подклассом) с SKAction.move:

func animateSwapCard(card1 :Card, card2: Card, duration:TimeInterval) {
    let inital = card1.position
    card1.run(SKAction.move(to: card2.position, duration: duration))
    card2.run(SKAction.move(to: inital, duration: duration))
}

Оба SKActions должны выполняться одновременно, но animateSwapCard () должен вернуться после обоих SKActions полностью сделано. Я попытался создать последовательность SKAction.sequence с обоими действиями и SKAction.wait, но она не сработала.

Функция вызывается несколько раз в другой функции:

override func viewDidLoad() {
    placeCards()
    // get refrences to cardA and cardB
    animateSwapCard(card1: cardA, card2: cardB, duration: 1)
    // get refrence to cardC
    animateSwapCard(card1: cardB, card2: cardC, duration: 1)
    // get refrences to card D and cardE
    animateSwapCard(card1: cardD, card2: cardE, duration: 1)
}

Что происходит, так это то, что второй и третий вызов animateSwapCard () начинается сразу после первого. Он не ждет, пока анимация закончится sh, прежде чем перейти к следующему. Все карты начинают двигаться в одно и то же время.

Что я хочу заархивировать, так это то, что cardA и cardB меняются местами. После того, как анимация закончена, cardB и card C меняются местами. После этого cardD и cardE должны сделать то же самое.

1 Ответ

2 голосов
/ 03 апреля 2020

Есть несколько способов сделать это

Проблема в том, что все действия запускаются одновременно. код не знает, что вам нужна задержка между действиями, потому что вы не сказали, чтобы она задерживалась.

Самое простое решение, которое должно помочь вам понять, что происходит, - это следующее.

override func viewDidLoad() {

    placeCards()

    var wait = SKAction.wait(forDuration: 1)

    // get refrences to cardA and cardB
    animateSwapCard(card1: cardA, card2: cardB, duration: 1)

    // get refrence to cardC
    self.run(wait) {
         animateSwapCard(card1: cardB, card2: cardC, duration: 1)
    }

    wait = SKAction.wait(forDuration: 2)
    // get refrences to card D and cardE
    self.run(wait) {
        animateSwapCard(card1: cardD, card2: cardE, duration: 1)
    }
}

func animateSwapCard(card1: Card, card2: Card, duration: TimeInterval) {
    let inital = card1.position
    card1.run(SKAction.move(to: card2.position, duration: duration))
    card2.run(SKAction.move(to: inital, duration: duration))
}

хотя этот метод уродлив, и если вы хотите сделать больше двух свопов, это становится болью в заднице.

Вы можете использовать замыкание завершения в функции.

func animateSwapCard(card1: Card, card2: Card, duration: TimeInterval, complete: () -> ()) {
    let inital = card1.position
    card1.run(SKAction.move(to: card2.position, duration: duration))
    card2.run(SKAction.move(to: inital, duration: duration)) {
        complete()
    }
}

и использовать его так же

override func viewDidLoad() {

    placeCards()

    // get refrences to cardA and cardB
    animateSwapCard(card1: cardA, card2: cardB, duration: 1) {

        // get refrence to cardC
        animateSwapCard(card1: cardB, card2: cardC, duration: 1) {

            // get refrences to card D and cardE
            animateSwapCard(card1: cardD, card2: cardE, duration: 1) { }
        }
    }
}
...