Search code examples
swiftsprite-kitalphaskactionskshapenode

Accessing properties of multiple SKShapeNodes


In my program I have a method called addObstacle, which creates a rectangular SKShapeNode with an SKPhysicsBody, and a leftward velocity.

func addObstacle(bottom: CGFloat, top: CGFloat, width: CGFloat){
    let obstacleRect = CGRectMake(self.size.width + 100, bottom, width, (top - bottom))
    let obstacle = SKShapeNode(rect: obstacleRect)
    obstacle.name = "obstacleNode"
    obstacle.fillColor = UIColor.grayColor()
    obstacle.physicsBody = SKPhysicsBody(edgeLoopFromPath: obstacle.path!)
    obstacle.physicsBody?.dynamic = false
    obstacle.physicsBody?.affectedByGravity = false
    obstacle.physicsBody?.contactTestBitMask = PhysicsCatagory.Ball
    obstacle.physicsBody?.categoryBitMask = PhysicsCatagory.Obstacle
    obstacle.physicsBody?.usesPreciseCollisionDetection = true   
    self.addChild(obstacle)
    obstacle.runAction(SKAction.moveBy(obstacleVector, duration: obstacleSpeed))
}

In a separate method, called endGame, I want to fade out all the obstacles currently in existence on the screen. All the obstacle objects are private, which makes accessing their properties difficult. If there is only one on the screen, I can usually access it by its name. However, when I say childNodeWithName("obstacleNode")?.runAction(SKAction.fadeAlphaBy(-1.0, duration: 1.0)), only one of the "obstacles" fades away; the rest remain completely opaque. Is there a good way of doing this? Thanks in advance (:


Solution

  • You could probably go with:

    self.enumerateChildNodesWithName("obstacleNode", usingBlock: {
        node, stop in 
        //do your stuff
    })
    

    More about this method can be found here.

    In this example I assumed that you've added obstacles to the scene. If not, then instead of scene, run this method on obstacle's parent node.

    And one side note...SKShapeNode is not performant solution in many cases because it requires at least one draw pass to be rendered by the scene (it can't be drawn in batches like SKSpriteNode). If using a SKShapeNode is not "a must" in your app, and you can switch them with SKSpriteNode, I would warmly suggest you to do that because of performance.

    SpriteKit can render hundreds of nodes in a single draw pass if you are using same atlas and same blending mode for all sprites. This is not the case with SKShapeNodes. More about this here. Search SO about this topic, there are some useful posts about all this.