Reputation: 57
In order to prevent a lot of the same code, I want to refer to every single node(all children of the same parent) on the scene with one call. I have a gate at the bottom of the scene and I want to detect if any node(many different nodes getting added to the scene) passes the y position of this gate.
This is how my update function looks now:
override func update(_ currentTime: TimeInterval) {
// code I want to simplify
if Cap.position.y < illustration2.position.y
|| Cap2.position.y < illustration2.position.y
|| Cap3.position.y < illustration2.position.y
|| Cap4.position.y < illustration2.position.y
|| Cap5.position.y < illustration2.position.y
|| Cap6.position.y < illustration2.position.y
|| Cap7.position.y < illustration2.position.y
|| Cap8.position.y < illustration2.position.y
|| Cap9.position.y < illustration2.position.y
|| Cap10.position.y < illustration2.position.y {
// Transitioning to game over
let transition = SKTransition.crossFade(withDuration: 0)
let gameScene = GameOver(size: self.size)
self.view?.presentScene(gameScene, transition: transition)
}
}
All Caps are children of illustration2, so I was thinking about something like:
//if the y position of any child is below the illustration2 y position the game over scene starts
if dontaiIllustration2.children.position.y < dontaiIllustration2.position.y {
}
Or another approach could be to check that the illustration2 node has the lowest y position from all nodes at the scene.
Upvotes: 0
Views: 152
Reputation: 1915
Not really proud of this but you can do a forEach
on the children of a parent node.
let node = SKNode()
var checker = false
node.children.forEach { (node) in
if node.position.y < illustration2.position.y {
checker = true
}
}
if checker {
// Game over
}
or you can enumerate them if you only want targets with specific names:
node.enumerateChildNodes(withName: "all can have same name") { (node, stop) in
if node.position.y < illustration2.position.y {
checker = true
}
}
You could also one-line it by using filter:
node.children.filter({$0.position.y < illustration2.position.y}).count > 0
Either way, i would put this in an extension of SKNode.
Upvotes: 1
Reputation: 16827
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.
Upvotes: 1