Timm Kent
Timm Kent

Reputation: 1268

How many SKNodes on one scene? Why is my performance so bad?

I am developing a card game, 52 cards, 20 are visible, the rest is on a "stack". There is no physics, nothing special, just SKSpriteNodes with PNG Images. I am running at 90% CPU on my iMAC and on an iPhone 5S it "feels" like one second until there is a reaction to touches. Is it a problem to have so many SKSpriteNodes on one scene? Or might the scaleFactor of .22 be the problem?

Where is my mistake?

Here I layout the cards

class PlayingCardView : SKSpriteNode {

    init(imageNamed: String, cardIndex: Int) {
        let cardTexture = SKTexture(imageNamed: imageNamed)
        let cardScaleFactor:CGFloat = 0.22  
        let cardSize = CGSizeMake(cardTexture.size().width * cardScaleFactor,cardTexture.size().height * cardScaleFactor)
        super.init(texture: cardTexture, color: nil, size: cardSize)
        self.name = "\(cardIndex)"
    }
}

// MARK: UpdateUI
func updateUI() {
        assert(game.cards.count > 0, "No Cards")
        if status == GameIs.Paused {return}
        removeAllCards()
        PlayingCardViews.removeAll(keepCapacity: false)

        var scaleFactor:CGFloat = 0.8
        var upOffset:CGFloat = 0.0
        var cardsLeft = 0

        // create spritenotes for all 52 cards
        for i in 0..<game.cards.count {
            let card = game.cardAtIndex(i)
            // all cards until cardPositions.count face up. the rest on the stack
            var (x,y) = (7,6)
            if i<cardPositions.count {
                (x,y) = cardPositions[i]
            }
            // determine real position from the grid information
            let xPos:CGFloat = realXForPositionX(x)
            let yPos:CGFloat = realYForPositionY(y)
            let image =  backgroundImageForCard(card)
            // we save the currents positon in the Model
            card.positionGrid = (x,y)
            let cardSprite = PlayingCardView(imageNamed: backgroundImageForCard(card), cardIndex:i)
            PlayingCardViews.append(cardSprite) 
            if !card.removed {
                cardSprite.position = CGPointMake(realXForPositionX(x),realYForPositionY(y))  
                cardLayer.addChild(cardSprite)
                ++cardsLeft  
            }
        }
        if cardsLeft == 0 { gameOver(0, timeLeft: secondsLeft) }
    }

Upvotes: 1

Views: 120

Answers (1)

Norman G
Norman G

Reputation: 769

Ok I just noticed it looks like you are adding all those sprites and setting up your scene in the Update method! You should just create a setup() { } method, add the sprites and setup in that, otherwise adding the cards gets called 60 times a second!

Call your custom setup method from didMoveToView (which is called only once) and then only call code to move or update the cards as is necessary for gameplay.

Upvotes: 1

Related Questions