Reputation: 8757
I have a function(touchesBegan) in a class which changes a property.
class Difficulty: SKScene {
var easy: SKSpriteNode?
var middle: SKSpriteNode?
var hard: SKSpriteNode?
var difficultLevel: DifficultLevel?
override func didMove(to view: SKView) {
self.easy = self.childNode(withName: "easy") as? SKSpriteNode
self.middle = self.childNode(withName: "middle") as? SKSpriteNode
self.hard = self.childNode(withName: "hard") as? SKSpriteNode
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches {
let location = touch.location(in: self)
if (easy?.contains(location))! {
difficultLevel = .easy
goToGameScene()
} else if (middle?.contains(location))! {
difficultLevel = .middle
goToGameScene()
} else if (hard?.contains(location))! {
difficultLevel = .hard
goToGameScene()
}
}
}
func goToGameScene() {
let gameScene = GameScene(size: self.size)
let crossFade = SKTransition.crossFade(withDuration: 2)
self.view?.presentScene(gameScene, transition: crossFade)
}
}
And I want a different class to access my changed difficultLevel
property, but if I create an object in a different class with let getDifficultLevel = Difficulty()
and do this:
enum DifficultLevel {
case easy
case middle
case hard
}
class GameScene: SKScene{
override func didMove(to view: SKView) {
let getDifficultLevel = Difficulty()
print(getDifficultLevel.difficultLevel)
switch getDifficultLevel.difficultLevel {
case .easy?: spawnTimer = Timer.scheduledTimer(timeInterval: 4, target: self, selector: #selector(self.createEnemy), userInfo: nil, repeats: true)
case .middle?: spawnTimer = Timer.scheduledTimer(timeInterval: 2, target: self, selector: #selector(self.createEnemy), userInfo: nil, repeats: true)
case .hard?: spawnTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(GameScene.createEnemy), userInfo: nil, repeats: true)
case .none:
print("nil!!!!")
}
}
}
It always prints nil. I don't understand why although I changed the property in the class Difficulty
itself in the function touchesBegan
.
Upvotes: 2
Views: 73
Reputation: 16837
The reason why your .difficultLevel is nil is because you never bother to set it. Learn how to walk through your code.
override func didMove(to view: SKView) {
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
func goToGameScene() {
Are the only functions in your class, and the only one these to set difficulty is touchesBegan
.
So let's go to your GameScene function:
override func didMove(to view: SKView) {
let getDifficultLevel = Difficulty()
print(getDifficultLevel.difficultLevel)
switch getDifficultLevel.difficultLevel {
case .easy?: spawnTimer = Timer.scheduledTimer(timeInterval: 4, target: self, selector: #selector(self.createEnemy), userInfo: nil, repeats: true)
case .middle?: spawnTimer = Timer.scheduledTimer(timeInterval: 2, target: self, selector: #selector(self.createEnemy), userInfo: nil, repeats: true)
case .hard?: spawnTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(GameScene.createEnemy), userInfo: nil, repeats: true)
case .none:
print("nil!!!!")
}
}
At what point between:
let getDifficultLevel = Difficulty()
print(getDifficultLevel.difficultLevel)
Does the touchesBegan function get called? (Hint: never)
Now you are most likely going to tell me, "touches begin does get called"
Well where did we go wrong?
let getDifficultLevel = Difficulty()
is creating a new scene, not using one already estableshed.
Now I am going to guess that Difficulty is actually your starting scene and you are somehow transitioning to GameScene.
Well you are going to need to pass that data over during transition. I recommend using userData
for this.
So when you present your GameScene, you are going to want to do something like this.
//self is the Difficulty scene
let gameScene = GameScene(...)
gameScene.userData = ["difficultLevel":self.difficultLevel]
self.view.presentScene(gameScene)
Then in your GameScene, you want to change your didMove to the following:
override func didMove(to view: SKView) {
let difficultLevel = userData!["difficultLevel"] as! DifficultLevel //If the code crashed here, this means we have a path that does not set userData, so we need to address that
print(difficultLevel)
switch difficultLevel {
case .easy?: spawnTimer = Timer.scheduledTimer(timeInterval: 4, target: self, selector: #selector(self.createEnemy), userInfo: nil, repeats: true)
case .middle?: spawnTimer = Timer.scheduledTimer(timeInterval: 2, target: self, selector: #selector(self.createEnemy), userInfo: nil, repeats: true)
case .hard?: spawnTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(GameScene.createEnemy), userInfo: nil, repeats: true)
case .none:
print("nil!!!!")
}
}
Now we have access to the difficult level provided by the previous scene.
Upvotes: 1