user6794148 user6794148 - 8 months ago 41
Swift Question

SpriteKit: How do I remove objects once they leave the screen?

I have a rock sprite that it is falling and every time it goes out of the screen I want to reset it back to the top and have it fall again. It should be a continuous cycle. Here's my code:

import SpriteKit
import GameplayKit

class GameScene: SKScene {

func addRock(){
var rock = self.childNode(withName: "rock")
rock?.physicsBody?.affectedByGravity = true
//self.addChild(rock!)
}

override func sceneDidLoad() {
//bRock = self.childNode(withName: "rock")
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
//addRock()
var rock = self.childNode(withName: "rock")
rock?.physicsBody?.affectedByGravity = true
/*if (Int((rock?.position.y)!) < Int((self.view?.scene?.view?.bounds.minY)!)){
print("out of screen")
rock?.removeFromParent()
addRock()
}*/
}


override func update(_ currentTime: TimeInterval) {
// Called before each frame is rendered
var rock = self.childNode(withName: "rock")
//rock?.physicsBody?.affectedByGravity = true
if (!intersects(rock!)){
print("out of screen")
rock?.removeFromParent()
addRock()
}

}
}


I have the rock coming on the screen and then falling. Once it leaves the screen, it does not reset and I get an error. I tried placing the reset code in both the touchesBegan and update functions but neither work. If someone could guide me to the correct path, that would be greatly appreciated.

Answer Source

The problem you're having is that you're removing the rock node from the scene but the addRock method doesn't actually add a new rock, it just finds the existing node if there is one and sets a property on its physicsBody. Instead of removing the node, you should just change its position.

Assuming your scene has the default anchor point of (0,0), you can reset the position like this:

override func update(_ currentTime: TimeInterval) {
    // Called before each frame is rendered
    if let rock = self.childNode(withName: "rock") {
    if !intersects(rock!) {
        print("out of screen")
        rock.position.y = size.height/2 // divided by 2 as discussed in comments
    }
}

That will reset the rock's position to the top of the scene and it should resume falling from there.