1

I am creating a card game and having trouble having SKActions run in a sequence across multiple SK Objects (Nodes, Textures, Labels, etc.). Any help would be much appreciated! In the example below, I am trying to create a "dealing" motion. Where 1 card gets dealt, some time elapses, then the next card gets dealt. I tried using this, but with 52 cards, it's not exactly the simplest approach.

First, I tried creating an array of SKActions for each card. However, I don't believe I can run the below using one command based on my understanding of the documentation. Each action needs to be run against the specific Sprite Object as opposed to running a whole sequence of actions across multiple Sprite Objects.

let dealAction = SKAction[]()
for card in deck {
    let move = SKAction.... 
    dealAction.append(move)
}
run.SKAction.sequence(dealAction) // This will not work. 

Then I tried this with the hope that the loop would complete each cards block of code before moving on to the next card. However, all the actions run at the same time. Now, I am a bit lost and I don't know exactly how to implement this efficiently. The only thing I could think of was creating a "timingIndex", where .2 seconds gets added to the wait time for each card. So even though they are all running at the same time, the wait time grows for each card. Not sure if this is the best way to approach the problem however and was hoping there was a more elegant solution.

for card in deck {
    let move = SKAction.... 
    let wait = SKAction.wait(forDuration: 1)
    card.run(SKAction.sequence[move, wait])
}

// Possible Solution
let timingIndex = 0.2
for card in deck {
    let move = SKAction.... 
    let wait = SKAction.wait(forDuration: timingIndex)
    card.run(SKAction.sequence[move, wait])
    timingIndex += 0.2
}

import SpriteKit
import UIKit

let screenH = 100
let screenW = 50

class Player {
    var handLocation: CGPoint
    var pile = [Card]()

    init() {
        handLocation = CGPoint(x: 100, y: 583)
    }
}

class Card: SKSpriteNode {

}

struct Game {
    var player1 = Player()
    var player2 = Player()
    var deck = [Card]()

    func dealDeck() {
        for card in deck {
            player1.pile.append(card) // This would theoretically loop through both players
            card.position = CGPoint(x: screenW / 2, y: screenH / 2)
            let move = SKAction.move(to: player1.handLocation, duration: 1)
            card.run(move)
        }
    }

}
SharpSharpLes
  • 302
  • 4
  • 20
  • *The only thing I could think of was creating a "timingIndex", where .2 seconds gets added to the wait time for each card*. Did that work out for you? If it does then there is probably nothing wrong with what you are doing. Sequential wait actions to act as completions is not so bad unless you are looking for very precise timing. If you're not, then you won't notice if it is off by 0.001 seconds anyway. – Left as an exercise Jun 06 '20 at 12:32
  • This did work! I am a little worried about the timing of the rest of the app and trying to get everything to sync up... so it doesn't really seem like a system wide solution. But for this example and problem, yes, it worked! – SharpSharpLes Sep 09 '20 at 18:43

1 Answers1

0

This worked! Worried about the use of this overall and if there exists a better solution still, but for the time being, this worked.

// Possible Solution
let timingIndex = 0.2
for card in deck {
    let move = SKAction.... 
    let wait = SKAction.wait(forDuration: timingIndex)
    card.run(SKAction.sequence[move, wait])
    timingIndex += 0.2
}
SharpSharpLes
  • 302
  • 4
  • 20