如何一次生成多个相同的SpriteNode?

时间:2017-01-21 20:48:55

标签: swift sprite-kit

所以我有3个不同的障碍物随机产生并在3秒后被移除,但是如果例如Obstacle1已经产生并且随机数字告诉程序产生另一个Obstacle1,我得到一个错误说

  

“因未捕获的异常而终止应用   'NSInvalidArgumentException',原因:'试图添加一个SKNode   已经有了父母“

继续使用Obstacle1的代码,其他两个几乎相同,只是名称不同:  func createObst1() { self.addChild(obst1) path = UIBezierPath(arcCenter: CGPoint(x: 0, y: -170), radius: circle.frame.size.height / 2 + obst1.frame.size.width / 2 - 4, startAngle: CGFloat(rad) * 2, endAngle: CGFloat(rad) + CGFloat(M_PI * 2.5), clockwise: true) let follow = SKAction.follow(path.cgPath, asOffset: false, orientToPath: true, duration: TimeInterval(roundDuration)) obst1.isHidden = false let fadeOutInstant = SKAction.fadeOut(withDuration: 0) let fadeIn = SKAction.fadeIn(withDuration: 0.3) let fadeOut = SKAction.fadeOut(withDuration: 0.3) let pause = SKAction.wait(forDuration: 2.4) let remove = SKAction.removeFromParent() let sequence = SKAction.sequence([fadeOutInstant, fadeIn, pause, fadeOut, remove]) let group = SKAction.group([follow, sequence]) obst1.run(group) }

我是否必须使用相同的代码创建多个Obstacle1函数,还是有其他方法可以解决我的问题?

以下是Code如何随机生成障碍物以防万一:func gameStarted() { Timer.scheduledTimer(timeInterval: TimeInterval(randomDelay), target: self, selector: #selector(GameScene.obstSwitch), userInfo: nil, repeats: true) }

func obstSwitch() {
let rand = arc4random_uniform(3)    
switch rand{
case 0:
    createObst1()

case 1:
    createObst2()

case 2:
    createObst3()

default:
    break
    }
}

1 个答案:

答案 0 :(得分:2)

试试这段代码:

class GameScene: SKScene, SKPhysicsContactDelegate {

    let obstacles = [
            SKSpriteNode(color:.brown, size:CGSize(width: 50, height: 50)),
            SKSpriteNode(color:.white, size:CGSize(width: 50, height: 50)),
            SKSpriteNode(color:.black, size:CGSize(width: 50, height: 50)),
        ]


    func getRandomObstacle(fromArray array:[SKSpriteNode])->SKSpriteNode{

        return array[Int(arc4random_uniform(UInt32(array.count)))]
    }


    func spawnObstacle(atPosition position:CGPoint) {

        if let obstacle = getRandomObstacle(fromArray: obstacles).copy() as? SKSpriteNode {

            obstacle.position = position

            //apply action that fade out and remove the node after 3 seconds

            let fadeOut = SKAction.fadeOut(withDuration: 3)
            let remove = SKAction.removeFromParent()

            let sequence = SKAction.sequence([fadeOut,remove])

            obstacle.run(sequence, withKey: "aKey")

            addChild(obstacle)

        }

    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

        if let touch = touches.first {

            let location = touch.location(in: self)
            spawnObstacle(atPosition: location)
        } 
    }  
}

此代码基本上会在每个水龙头上产生一个随机障碍物的副本。因为您制作副本,所以不用担心您目前遇到的错误。

要使用SKAction生成节点,正如您所说,作为Timer的替代方法,您将创建一个包含两个元素的操作序列,一个等待操作和一个生成节点的块。这就是动作序列的样子:

override func didMove(to view: SKView) {
        //Setup scene and nodes

        let wait = SKAction.wait(forDuration: 0.5)

        let spawn = SKAction.run({[unowned self] in

            //calculate obstalce initial position here, eg. randomize it

            let spawnLocation = //...
            self.spawnObstacle(atPosition: spawnLocation)
        })

        let sequence = SKAction.sequence([wait, spawn])
        let loop = SKAction.repeatForever(sequence)
        run(loop , withKey:"spawning")

    }