bandoy123
bandoy123

Reputation: 243

Attemped to add a SKNode which already has a parent error

I am getting the error: "Attemped to add a SKNode which already has a parent" when trying to run my game.

If I add the SKSpriteNode locally into the function, it runs fine. But when I try and declare it globally, I get that error. Any help to resolve this error would be great. I assume it has to do with the self.bee.removeFromParent() but I can't get it to work.

let bee = SKSpriteNode(imageNamed: "Bee")

runAction(SKAction.repeatActionForever(
    SKAction.sequence([
        SKAction.runBlock(addBee),
        SKAction.waitForDuration(0.5)
        ])
    ))

func addBee() {

    bee.name = "Bee"
    let actualY = random(min: 0, max: siz    e.height+bee.size.height ) // random

    bee.position = CGPoint(x: size.width + bee.size.width/2, y: actualY)
    self.addChild(bee)

    let slopeToPlayer = (bee.position.y - player.position.y) / (bee.position.x - player.position.x)
    let constant = bee.position.y - slopeToPlayer * bee.position.x

    let finalX : CGFloat = bee.position.x < player.position.x ? 500.0 : -500.0 // Set it to somewhere outside screen size

    let finalY = constant +  slopeToPlayer * finalX

    let distance = (bee.position.y - finalY) * (bee.position.y - finalY) + (bee.position.x - finalX) * (bee.position.x - finalX)
    let beeSpeed = random(min: CGFloat(50), max: CGFloat(150))
    let timeToCoverDistance = sqrt(distance) / beeSpeed

    let moveAction = SKAction.moveTo(CGPointMake(finalX, finalY), duration: NSTimeInterval(timeToCoverDistance))
    let removeAction = SKAction.runBlock { () -> Void in
        self.bee.removeFromParent()
    }
    bee.runAction(SKAction.sequence([moveAction,removeAction]))


}

Upvotes: 6

Views: 7538

Answers (1)

rakeshbs
rakeshbs

Reputation: 24572

You cannot add a single instance of the same SKNode twice. That is like saying a person can exist at two places at once. When you create the Bee node globally,outside the scope of the addBee function, you are trying to add the same instance of Bee again and again.

If you want to add multiple nodes, you should create separate instances of the nodes. This is why creating them locally from within the function works.

func addBee() {

    let bee = SKSpriteNode(imageNamed: "Bee")
    bee.name = "Bee"
    addChild(bee)
}

To get a reference of the colliding nodes.

func didBeginContact(contact: SKPhysicsContact) {

    var bodyA : SKPhysicsBody!
    var bodyB : SKPhysicsBody!

    if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask
    {
        bodyA = contact.bodyA!
        bodyB = contact.bodyB!
    }
    else
    {
        bodyB = contact.bodyA!
        bodyA = contact.bodyB!
    }

    // The two nodes that have collided
    let node1 = bodyA.node 
    let node2 = bodyB.node

}

Upvotes: 13

Related Questions