How to Enumerate All Nodes in a Sprite Kit Scene

How to enumerate ALL nodes in a Sprite Kit scene?

Yep, use enumerateChildNodesWithName:usingBlock: and pass //* as the node name. You should be able to call that on any node.

It's actually one of the examples in Apple's docs:

//* This search string matches every node in the node tree.

iOS SpriteKit Get All nodes in a current scene and make the application universal.

  1. in Scene.m, you can use self.children to get all the SKSprite Nodes
  2. http://www.raywenderlich.com/49695/sprite-kit-tutorial-making-a-universal-app-part-1

using flatMap to enumerate SpriteKit nodes

What I learned was that the node tree is really a tree and you have to start looking on the right branch to get results. The answer to my question is:

let enemies = childNodeWithName("//level")!.children.flatMap { ($0 as? SomeEnemyClass) }

or

let enemies = childNodeWithName("//level")!.children.filter { $0 is SomeEnemyClass }

This is not an answer to my question, but it works too...

 self.enumerateChildNodesWithName("//*") {
node, stop in
if (node.name == "enemy") {
print(node)
}
}

Thank you to everyone who offered their input. It got me pointed in the right direction.

How can I get the number of skspritenodes in a scene?

if you're doing this inside the scene itself you can do

if (self.children.count == x) {
yourFunction() //call your function
}

or

if (children.count == x) {
yourFunction() //call your function
}

in response to your comment:

there's an update method that runs every frame in sprite kit. Use it like this:

override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
if (children.count == x) {
yourFunction() //call your function
}
}

SpriteKit: find all descendants of SKNode of certain class?

What we did was pass a block to the SKNode function that finds nodes by name, and used * as the search term to avoid assigning a name to desired nodes.

    var descendants = [CustomClass]()
nodeToSearch.enumerateChildNodes(withName: ".//*") { node, stop in
if node is CustomClass {
descendants.append(node as! CustomClass)
}
}

How to refer to multiple SKNodes at once in SpriteKit?

You can’t. You need to place them into a collection (array, dictionary, set, etc) and then find a way to traverse through them with something like foreach, map, compactMap (formally flatMap), reduced, etc. in your case, I would use reduce.

let caps = [Cap1,Cap2,Cap3,Cap4,Cap5,Cap6,Cap7,Cap8,Cap9,Cap10]
let result = caps.reduce(false,{value,cap in return value || cap.position.y < illustration2.position.y})
if result {
// Transitioning to game over

let transition = SKTransition.crossFade(withDuration: 0)
let gameScene = GameOver(size: self.size)
self.view?.presentScene(gameScene, transition: transition)
}

What this is doing, is going through each of your nodes, and evaluating the current equation with the previous result.

So we start at a false, then it will check if cap y > illustration y. If true, then our value becomes true, and this value carries over to the next cap. It repeats this until you run out of caps, and then returns the final value, which will be a false or a true.

iOS enumerateChildNodeswithName to access ALL physics bodies

This worked for me:

enumerateChildNodesWithName("//.") { (node, _) -> Void in
print("Node: \(node.name)")
}

About // :

When placed at the start of the search string, this specifies that the
search should begin at the root node and be performed recursively
across the entire node tree.

About . :

Refers to the current node.

Also this might work for you as well (if you want to find all physics bodies within a given rectangle):

self.physicsWorld.enumerateBodiesInRect(frame) { (body, _) -> Void in
print(body.node?.name)
}

An efficient way to find all SKNodes within a certain distance from a given point?

To determine if one or more nodes in the scene are within a fixed distance of a touch event, 1) compute the distance between the touch and each node and 2) compare if that distance is less than or equal to a constant. Here's an example of how to do that:

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
if let touch = touches.first {
let location = touch.locationInNode(self)
let nodes = nodesNearPoint(self, point:location, maxDistance: 30)
if nodes.count > 0 {
print("node is near touch point")
}
}
}

// Returns an array of all SKNode objects in the subtree that near the specified point.
// If no nodes are near the point, an empty array is returned.
func nodesNearPoint(container:SKNode, point:CGPoint, maxDistance:CGFloat) -> [SKNode] {
var array = [SKNode]()
for node in container.children {
// Only test sprite nodes (optional)
if node is SKSpriteNode {
let dx = point.x - node.position.x
let dy = point.y - node.position.y

let distance = sqrt(dx*dx + dy*dy)
if (distance <= maxDistance) {
array.append(node)
}
}
}
return array
}


Related Topics



Leave a reply



Submit