Reputation: 1
i just simply trying to use SKEmitterNode and SKSpriteNode but i'm getting error on second line of my code
startfield.position = CGPoint.init(x:0,y:1200)
and error is like
"fatal error: unexpectedly found nil while unwrapping an Optional value"
Getting 2 times and also this one
"does not have sandbox access for frZQaeyWLUvLjeuEK43hmg and IS NOT appropriately entitled"
i didn't understand optional concept so because of that i'm not able to solve it ..
class GameScene: SKScene {
var startfield : SKEmitterNode!
var player : SKSpriteNode!
override func didMove(to view: SKView) {
startfield = SKEmitterNode(fileNamed: "Starfield")
startfield.position = CGPoint.init(x: 0, y: 1200)
startfield.advanceSimulationTime(10)
self.addChild(startfield)
startfield.zPosition = -1
//define Player
player = SKSpriteNode(imageNamed: "shuttle")
player.position = CGPoint(x: self.frame.width/2, y: player.size.height/2 + 20)
self.addChild(player)
}
override func update(_ currentTime: TimeInterval) {
// Called before each frame is rendered
}
}
Upvotes: 0
Views: 379
Reputation: 131501
When you create a variable with a !
after the type, you make it "implicitly unwrapped". In practice, this means that if the variable is nil and you try to reference it, you crash.
Get rid of the !
in your declarations.
var startfield : SKEmitterNode?
And then change your didMove function to use a guard:
override func didMove(to view: SKView) {
startfield = SKEmitterNode(fileNamed: "Starfield")
guard let startfield = startfield else {
print("startfield is nil!")
return
}
startfield.position = CGPoint.init(x: 0, y: 1200)
startfield.advanceSimulationTime(10)
self.addChild(startfield)
startfield.zPosition = -1
//define Player
player = SKSpriteNode(imageNamed: "shuttle")
player.position = CGPoint(x: self.frame.width/2, y: player.size.height/2 + 20)
self.addChild(player)
}
Upvotes: 0
Reputation:
The line:
startfield = SKEmitterNode(fileNamed: "Starfield")
Can return a nil
if the file isn't found but you have it stored in an implicitly-unwrapped Optional
:
var startfield : SKEmitterNode!
So the system treats it as non-nil
but it's really nil
. Then when you try to assign a property for that nil
:
startfield.position = CGPoint.init(x: 0, y: 1200)
// should really be: CGPoint(x: 0, y: 1200)
Everything blows up and you get a fatal error.
Instead, check that the file loads correctly and then do your assignment:
override func didMove(to view: SKView) {
// Load the file into a `SKEmitterNode?` and use optional binding
// to attempt to unwrap into a `SKEmitterNode`.
guard let emitter = SKEmitterNode(fileNamed: "Starfield") else {
// Unwrapping failed, crash with an appropriate message.
fatalError("File \"Starfield\" not found.")
}
// Unwrapping succeeded, continue
startfield = emitter
// ...
}
The reason it loads into an SKEmitterNode?
in the first place is due to the loading being performed in a failable initializer inherited from SKNode
: init(fileNamed:)
convenience init?(fileNamed filename: String)
Optional Binding is when you use the construct if let
to unwrap an Optional
.
Upvotes: 1
Reputation: 1607
Redeclare your starfield
variable (mistyped as startfield
?) such that it allows nil values:
var starfield: SKEmitterNode?
This is necessary as SKEmitterNode(fileNamed:)
is an optional initialiser, i. e. one that may return nil
. Prior to further usage of this variable test if for not being nil, e. g. using a guard
statement:
guard let starfield = starfield else { return }
For the remainder of your function starfield
is non-nil now.
Upvotes: 1