Reputation: 111
Hey guys im having a huge problem with my Sprite Kit game. Im new to it and im trying to do a kind of asteroids game just to do exercise what i learnt.
My problem is, my asteroids are infinite, they don't stop unless the player is hit. My code is the follows:
For the meteor:
func addMeteor() {
let bigMeteor = SKSpriteNode(imageNamed: "meteor1")
let bigMeteorAux = bigMeteor
let sizeX = UInt32(CGRectGetMaxX(self.frame))
let randomX = CGFloat(arc4random_uniform(sizeX))
var impulse : CGVector!
bigMeteorAux.position = CGPoint(x: randomX, y: size.height + 100)
impulse = CGVector(dx: 0, dy: -30)
bigMeteorAux.physicsBody = SKPhysicsBody(texture: bigMeteor.texture, size: bigMeteor.size);
bigMeteor.physicsBody?.affectedByGravity = false
bigMeteor.physicsBody?.allowsRotation = false
bigMeteorAux.physicsBody?.friction = 0.0
bigMeteorAux.physicsBody!.categoryBitMask = CollisionCategoryAsteroids
bigMeteorAux.name = "Asteroid"
foregroundNode!.addChild(bigMeteorAux)
bigMeteorAux.physicsBody!.applyImpulse(impulse)
}
Im calling the function with an action:
runAction(SKAction.repeatActionForever(
SKAction.sequence([
SKAction.runBlock(addMeteor),
SKAction.waitForDuration(1.0)
])
))
Perfect until now, the game works just fine. This is the player code:
playerNode = SKSpriteNode(imageNamed: "spaceshipv2")
playerNode!.physicsBody = SKPhysicsBody(texture: playerNode!.texture, size: playerNode!.size);
playerNode!.xScale = 0.5
playerNode!.yScale = 0.5
playerNode!.position = CGPoint(x: size.width / 2.0, y: 220.0)
playerNode!.physicsBody!.linearDamping = 1.0
playerNode!.physicsBody!.allowsRotation = false
playerNode!.physicsBody?.affectedByGravity = false
playerNode!.physicsBody!.categoryBitMask = CollisionCategoryPlayer
playerNode!.physicsBody!.contactTestBitMask =
CollisionCategoryAsteroids
playerNode!.name = "Player"
//addChild(playerNode!)
foregroundNode!.addChild(playerNode!)
And for the last the contact func:
func didBeginContact(contact: SKPhysicsContact) {
var nodeB = contact.bodyB!.node!
if nodeB.name == "Asteroid" {
println("Touched")
nodeB.removeFromParent()
}
}
So my problem start with the nodeB, for some reason sometimes when the Asteroid hit the player this code works just fine but other times when the asteroid hit the player the game crashes and i get
fatal error: unexpectedly found nil while unwrapping an Optional value
After the program enters the contact function.
Any ideas or solution about how to fix this? Thx a lot! =)
Upvotes: 1
Views: 1163
Reputation: 4649
I'm not sure why the node is coming up nil, but you can avoid the crash by not force unwrapping the nil values:
if let nodeB = contact.bodyB?.node?
if nodeB.name == "Asteroid" {
println("Touched")
nodeB.removeFromParent()
}
}
Then that bit of code will only run if those optionals can be successfully unwrapped.
Upvotes: 1
Reputation: 80271
The crash comes from one of the two forced unwrap calls: bodyB!
and node!
. By writing it like this, you are asserting that you are sure they will never be nil
.
The way to find the case where one of these is nil, break up the code into lines that you can check with a breakpoint.
var bodyB = contact.bodyB
if bodyB == nil {
// breakpoint here
}
var nodeB = bodyB!.node
if nodeB == nil {
// breakpoint here
}
if nodeB!.name = "Asteroid" // etc.
Once the code stops you can examine the objects and try to find out why they are nil
and fix the problem.
Upvotes: 1