Reputation: 1
I am trying clouds move up and spawn but I keep getting
'terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attemped to add a SKNode which already has a parent: name:'(null)' texture:[ 'CLOUD' (746 x 497)] position:{198.66667175292969, 1227.987060546875} scale:{0.30, 0.30} size:{223.80000305175781, 149.10000610351562} anchor:{0.5, 0.5} rotation:0.00'. '
I'm not sure what's going wrong any help would be much appreciated
let cloud1 = SKSpriteNode(imageNamed: "CLOUD")
let cloud2 = SKSpriteNode(imageNamed: "CLOUD")
class GameScene: SKScene {
override func didMove(to view: SKView) {
self.anchorPoint = CGPoint(x: 0.5, y: 0.5)
setUp()
}
func setUp() {
let block = SKAction.run ({
self.spawnClouds()
if (cloud1.position.y > self.size.height) {
cloud1.removeFromParent()
cloud2.removeFromParent()
}
})
let wait = SKAction.wait(forDuration: 9)
let action = SKAction.repeat(block, count: 10)
let removes = SKAction.removeFromParent()
let sequence = SKAction.sequence([block, wait, action, removes])
self.run(sequence)
}
@objc func spawnClouds() {
let gapHeight = self.frame.width / 9
let movementAmount = arc4random() % UInt32(self.frame.width / 2)
let cloudOffset = CGFloat(movementAmount) - self.frame.width / 4
// let cloud1 = SKSpriteNode(imageNamed: "CLOUD")
cloud1.xScale = 0.3
cloud1.yScale = 0.3
cloud1.zPosition = 1
self.addChild(cloud2)
cloud2.xScale = 0.3
cloud2.yScale = 0.3
cloud2.zPosition = 1
cloud1.position = CGPoint(x:self.frame.minX / 2 + gapHeight / 5 + cloudOffset , y: self.frame.minY )
cloud2.position = CGPoint(x:self.frame.maxX / 2 + gapHeight / 5 + cloudOffset , y: self.frame.minY )
self.addChild(cloud1)
var distanceToMove = CGFloat(self.frame.size.width + 2.0 * cloud1.frame.width)
let moveCloud = SKAction.move(by: CGVector(dx:0, dy:25 * self.frame.width), duration: TimeInterval(self.frame.height / 15 ))
let newaction = SKAction.removeFromParent()
let new = SKAction.sequence([moveCloud, newaction])
cloud1.run(new)
cloud2.run(new)
}
override func update(_ currentTime: TimeInterval) {
if cloud2.position.y > size .height {
cloud1.removeFromParent()
cloud2.removeFromParent()
}
}
}
Upvotes: 0
Views: 36
Reputation: 8134
cloud1 and cloud2 are properties i.e. visible everywhere. So when you do addChild(cloud1)
and addChild(cloud2)
these are not newly create sprites but are the same ones you've added before, hence the message 'Attempting to add an SKNode that already has a parent'
In a function that is designed to spawn nodes, you usually create a new SKNode to spawn each time, just like your line of code that is commented out:
// let cloud1 = SKSpriteNode(imageNamed: "CLOUD")
This will make sure that cloud1 is a new node each time.
You should also be doing this for cloud2.
Upvotes: 1
Reputation: 11531
Two things, the first is action should be a sequence.
// let action = SKAction.repeat( block, count: 10)
let action = SKAction.repeat( SKAction.sequence( [block,wait]), count: 10)
second ,the timing should be perfect around 9s, i.e. self.frame.height / 15
//let moveCloud = SKAction.move(by: CGVector(dx:0, dy:25 * self.frame.width), duration: TimeInterval(self.frame.height / 15 ))
so this could be :
let moveCloud = SKAction.move(by: CGVector(dx:0, dy:2.5 * self.frame.width), duration: TimeInterval(self.frame.height / 150 ))
Upvotes: 0