How to transition scenes in Swift

23,278

Solution 1

To start with your second question, it's kind of up to you. If you wish to, you can continue to follow the Objective-C convention of having one class per file, although this isn't a requirement, and wasn't in Objective-C either. That being said, if you have a couple of classes that are tightly related, but aren't made up of much code, it wouldn't be unreasonable to have them grouped in a single file. Just do what feels right, and don't make a huge blob of code in a single file.

Then for your first questions... Yes, you had a good deal of it already. Basically, from where you got up to, you need to create the instance of GameScene through its size: initializer. From there, you just set the properties and call present.

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    super.touchesBegan(touches, withEvent: event)

    guard let location = touches.first?.locationInNode(self),
        let scene = scene,
        nodeAtPoint(location) == "Game Button" else {
        return
    }

    let transition = SKTransition.reveal(
        with: .down, 
        duration: 1.0
    )

    let nextScene = GameScene(size: scene.size)
    nextScene.scaleMode = .aspectFill

    scene.view?.presentScene(nextScene, transition: transition)
}

Solution 2

if you have to work on touch-begain or node action , Then use it:

override func touchesBegan(touches: NSSet!, withEvent event: UIEvent!) {
        let touch = touches.anyObject() as UITouch
        if CGRectContainsPoint(btncloseJump.frame, touch.locationInNode(self)) {
            self.scene.removeFromParent()
            btncloseJump.removeFromParent()
            let skView = self.view as SKView
            skView.ignoresSiblingOrder = true
            var scene: HomeScene!
            scene = HomeScene(size: skView.bounds.size)
            scene.scaleMode = .AspectFill
            skView.presentScene(scene, transition: SKTransition.fadeWithColor(SKColor(red: 25.0/255.0, green: 55.0/255.0, blue: 12.0/255.0, alpha: 1), duration: 1.0))
        }
    }
Share:
23,278
Narwhal
Author by

Narwhal

Updated on November 30, 2020

Comments

  • Narwhal
    Narwhal over 3 years

    In Objective-C, using Sprite-Kit, I would successfully use something like the following code in Objective-C to bring up a new scene

    if ([touchedNode.name  isEqual: @"Game Button"]) {
            SKTransition *reveal = [SKTransition revealWithDirection:SKTransitionDirectionDown duration:1.0];
            GameScene *newGameScene = [[GameScene alloc] initWithSize: self.size];
            //  Optionally, insert code to configure the new scene.
            newGameScene.scaleMode = SKSceneScaleModeAspectFill;
            [self.scene.view presentScene: newGameScene transition: reveal];
        }
    

    In trying to port my simple game to Swift, so far I have this working...

    for touch: AnyObject in touches {
            let touchedNode = nodeAtPoint(touch.locationInNode(self))
            println("Node touched: " + touchedNode.name);
            let touchedNodeName:String = touchedNode.name
    
            switch touchedNodeName {
            case "Game Button":
                println("Put code here to launch the game scene")
    
            default:
                println("No routine established for this")
            }
    

    But I do not know what code to write to actually transition to another scene. Question(s):

    1. Can someone please provide an example of using SKTransition with Swift?
    2. Would you normally create another "file" to put the other scene code in for the other scene, assuming you would have under Objective-C, or is there something about using Swift that means I should approach it differently?

    Thank you

    • David Skrundz
      David Skrundz almost 10 years
      2. Swift actually makes it easier to use multiple files since it automagically imports all files in the module. There isn't any reason not to follow the same patterns as with Objective-C
  • Narwhal
    Narwhal almost 10 years
    That worked. Thank you. Just a note for people who are almost as challenged as me... the "GameScene" in "GameScene(size: self.scene.size)" just refers to the SpriteKit file name you created (it is not a special reserved phrase).
  • zeeple
    zeeple over 9 years
    What happens to the scene you are transitioning away from? Will it keep running or do you need to deliberately pause it? If there is some action happening on the scene that you are transitioning away from it would seem that could affect your game.
  • Mick MacCallum
    Mick MacCallum over 9 years
    @user1639164 By default both the outgoing and the incoming scenes are paused during the transition. If you wish to alter this behavior, it can be done by changing the values of the SKTransition's pausesIncomingScene and pausesOutgoingScene properties.
  • Nate4436271
    Nate4436271 over 9 years
    this answer helped me as well.
  • Nick
    Nick over 6 years
    On your "transition": 'Down' has been renamed to 'down' & 'revealWithDirection(_:duration:)' has been renamed to 'reveal(with:duration:)'. On the nextScene.scaleMode, 'AspectFill' has been renamed to 'aspectFill'