Reputation: 168
I have a main screen which has a button, when this button is pressed it should transition immediately to another scene, but it doesn't. It actually takes a few seconds. Is there a way that I could load all the nodes in that scene beforehand? (Example: in the games load screen)
This is my code:
let pressButton = SKAction.setTexture(SKTexture(imageNamed: "playButtonP.png"))
let buttonPressed = SKAction.waitForDuration(0.15)
let buttonNormal = SKAction.setTexture(SKTexture(imageNamed: "playButton.png"))
let gameTrans = SKAction.runBlock(){
let doors = SKTransition.doorsOpenHorizontalWithDuration(0)
let levelerScene = LevelerScene(fileNamed: "LevelerScene")
self.view?.presentScene(levelerScene, transition: doors)
}
playButton.runAction(SKAction.sequence([pressButton,buttonPressed,buttonNormal,gameTrans]))
Upvotes: 4
Views: 1729
Reputation: 22969
You could preload the SKTexture
s you're using in LevelerScene
before presenting the scene. Then, once the loading has finished you would then present the scene. Here's an example from the Apple's Documentation, translated to Swift:
SKTexture.preloadTextures(arrayOfYourTextures) {
if let scene = GameScene(fileNamed: "GameScene") {
let skView = self.view as! SKView
skView.presentScene(scene)
}
}
In your case you have a couple of options:
1.
Keep an array of the textures, which you need to use in LevelerScene
, that you preload in GameScene
:
class LevelerScene : SKScene {
// You need to keep a strong reference to your textures to keep
// them in memory after they've been loaded.
let textures = [SKTexture(imageNamed: "Tex1"), SKTexture(imageNamed: "Tex1")]
// You could now reference the texture you want using the array.
//...
}
Now in GameScene
, when the user presses the button:
if let view = self.view {
let leveler = LevelerScene(fileNamed: "LevelerScene")
SKTexture.preloadTextures(leveler.textures) {
// Done loading!
view.presentScene(leveler)
}
}
There's no way you can get around having to wait a little bit, but taking this approach the main thread won't get blocked and you'll be able to interact with GameScene
whilst LevelerScene
is loading.
You could also use this approach to make a loading SKScene
for LevelerScene
. GameScene
would take you to the loading scene, which would load the textures and then move you to LevelerScene
once it was complete.
It's important to note that because the reference to the textures is in LevelerScene
, once LevelerScene
is deinit
-ed the textures will be removed from memory. Therefore, if you want to go back to LevelerScene
you'll need to load the textures again.
2. You could use SKTexture.preloadTextures
in GameViewController
before any SKScene
s have been presented. You'd need to keep a strong reference to these textures (perhaps in a singleton) which you could then reference in LevelerScene
(or anywhere else you needed them in the app).
With this approach, because the SKTexture
s are stored outside of a scene, they won't be removed from memory when you transition to the next scene. This means you won't have to load the textures again if you leave and then go back to a scene. However, if you've got a lot of textures taking up a lot of memory you could run into some memory issues.
For more information see Preloading Textures Into Memory from Working with Sprites.
Hope that helps!
Upvotes: 3