How to spawn Multiple of the same SpriteNode at once?

大城市里の小女人 提交于 2019-12-21 06:01:11

问题


So I have 3 different obstacles which spawn randomly and get removed after 3 seconds, but if for example Obstacle1 is already spawned and the random Number tells the program to spawn another Obstacle1, I get a Error that says

"Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attemped to add a SKNode which already has a parent"

heres the code of Obstacle1, the other two are almost the same just the names are different: 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) }

Do I have to create multiple Obstacle1 functions with the same Code in it or is there a other way do solve my problem?

Here's also the Code how I randomly spawn the Obstacles in case it helps: 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:


Try this code:

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

This code basically spawn a copy of an random obstacle on every tap. Because you make copies, there are no worries about the error you are getting currently.

To use SKAction to spawn nodes, as you said, as an alternative to Timer you would create an action sequence with two elements, a wait action, and a block that spawns a node. This is how action sequence might look like:

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

    }


来源:https://stackoverflow.com/questions/41784340/how-to-spawn-multiple-of-the-same-spritenode-at-once

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!