meobud
meobud

Reputation: 13

SKSpriteNode not able to have multiple children

I'm trying to have multiple sprite nodes of the same type/parent, but when I try to spawn another node I get an error. 'NSInvalidArgumentException', reason: 'Attemped to add a SKNode which already has a parent'

Here's my code:

import SpriteKit

class GameScene: SKScene {
    //global declarations
    let player = SKSpriteNode(imageNamed: "mage")
    let fireball = SKSpriteNode(imageNamed: "fireball")

    override func didMoveToView(view: SKView) {
        /* Setup your scene here */
        createScene()
    }
    override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
        /* Called when a touch begins */
        for touch in (touches as! Set<UITouch>) {
            let location = touch.locationInNode(self)
            spawnFireball(location)

        }
    }
    override func update(currentTime: CFTimeInterval) {
        /* Called before each frame is rendered */
        self.enumerateChildNodesWithName("fireball", usingBlock: ({
            (node,error) in
            if (self.fireball.position.x < -self.fireball.size.width/2.0 || self.fireball.position.x > self.size.width+self.fireball.size.width/2.0
                || self.fireball.position.y < -self.fireball.size.height/2.0 || self.fireball.position.y > self.size.height+self.fireball.size.height/2.0) {
                self.fireball.removeFromParent()
                self.fireball.removeAllChildren()
                self.fireball.removeAllActions()
            }
        }))
    }
    func createScene() {
        //player
        player.size = CGSizeMake(100, 100)
        player.position = CGPointMake(self.frame.size.width/2, self.frame.size.height/2 + 50)
        player.zPosition = 2.0
        self.addChild(player)
    }
    func spawnFireball(point: CGPoint) {
        //setup
        fireball.name = "fireball"
        fireball.size = CGSizeMake(100, 50)
        let fireballCenter = CGPointMake(fireball.size.width / 4 * 3, fireball.size.height / 2)
        fireball.position = player.position
        fireball.physicsBody = SKPhysicsBody(circleOfRadius: fireball.size.height/2, center: fireballCenter)
        fireball.physicsBody?.affectedByGravity = false
        //action
        var dx = CGFloat(point.x - player.position.x)
        var dy = CGFloat(point.y - player.position.y)
        let magnitude = sqrt(dx * dx + dy * dy)
        dx /= magnitude
        dy /= magnitude
        let vector = CGVector(dx: 32.0 * dx, dy: 32.0 * dy)

        var rad = atan2(dy,dx)
        fireball.runAction(SKAction.rotateToAngle(rad, duration: 0.0))
        self.addChild(fireball)
        fireball.physicsBody?.applyImpulse(vector)
    }
}

Upvotes: 1

Views: 168

Answers (1)

BradzTech
BradzTech

Reputation: 2835

You need to instantiate another SKSpriteNode. In your existing code, you create a single fireball and add it to the scene; your program crashes when you try to add the same fireball again.

First, remove your let fireball = SKSpriteNode... line. Move it to inside the spawnFireball() method, like so:

func spawnFireball(point: CGPoint) {
    let fireball = SKSpriteNode(imageNamed: "fireball")
    //Insert all customization here (your existing code should mostly work)
    self.addChild(fireball)
}

Because the fireball variable is a local variable, you can now instantiate a new one every time you call the function. Now, just change your update() method to properly use enumerateChildrenWithName() by getting changing every self.fireball to just node.

This way, the code will loop through every existing fireball that is currently on the scene, rather than your current code, which only allows you to create one fireball.

Upvotes: 2

Related Questions