SKSpriteNode 不能有多个 children

SKSpriteNode not able to have multiple children

我试图拥有多个相同 type/parent 的 sprite 节点,但是当我尝试生成另一个节点时出现错误。 'NSInvalidArgumentException',原因:'Attemped to add a SKNode which already has a parent'

这是我的代码:

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)
    }
}

您需要实例化另一个 SKSpriteNode。在您现有的代码中,您创建一个火球并将其添加到场景中;当您尝试再次添加相同的火球时,您的程序崩溃了。

首先,删除 let fireball = SKSpriteNode... 行。将其移动到 spawnFireball() 方法内部,如下所示:

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

因为fireball变量是局部变量,现在每次调用函数时都可以实例化一个新变量。现在,只需将 update() 方法更改为正确使用 enumerateChildrenWithName(),方法是将每个 self.fireball 更改为仅 node

这样,代码将遍历场景中当前存在的每个现有火球,而不是您当前的代码,它只允许您创建一个火球。