Swift シーン管理クラスを使ってゲーム画面を遷移させる


タイトル画面 → ゲーム画面 → 結果画面 の画面遷移を、シーン管理クラスを使って実装してみました。自分用のメモです。


```lang:GameViewController.swift
class GameViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let gameView = GameView(frame: self.view.frame)
        self.view = gameView        
    }

```

・シーンを管理するクラス

```lang:SceneManager.swift
import Foundation
import SpriteKit

class SceneManager: NSObject {
    
    //タイトルシーン
    class func titleScene(size: CGSize) -> TitleScene {
        let scene = TitleScene(size: size)
        return scene
    }
    
    //ゲームシーン
    class func gameScene(size: CGSize) -> GameScene {
        let scene = GameScene(size: size)
        return scene
    }
    
    //結果シーン
    class func resultScene(size: CGSize) -> ResultScene {
        let scene = ResultScene(size: size)
        return scene
    }
    
    //シーン切り替え
    class func changeScene(view: SKView, New newScene: SKScene, Duration sec: NSTimeInterval) {
        let transition = SKTransition.fadeWithDuration(sec)
        view.presentScene(newScene, transition: transition)
    }
}

```
・タイトル画面

```lang:TItleScene
import Foundation
import SpriteKit

class TitleScene: SKScene {
    
    var changeSceneDelegate: ChangeSceneProtocol!
    
    override func didMoveToView(view: SKView) {
        
        self.backgroundColor = UIColor.orangeColor()
        
        println("TitleScene")
        
        let label = SKLabelNode()
        label.text = "Title Scene"
        label.fontSize = 50
        label.fontColor = UIColor.blackColor()
        label.position = CGPoint(x: self.frame.width/2.0, y: self.size.height/2.0)
        self.addChild(label)
    }
    
    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
        changeSceneDelegate.changeScene(self.scene!)
    }
}

```
・ゲーム画面

```lang:GameScene.swift
import Foundation
import SpriteKit

class GameScene: SKScene {
    
    var changeSceneDelegate: ChangeSceneProtocol!
    
    override func didMoveToView(view: SKView) {
        
        self.backgroundColor = UIColor.yellowColor()
        
        println("GameScene")
        
        let label = SKLabelNode()
        label.text = "Game Scene"
        label.fontSize = 50
        label.fontColor = UIColor.blackColor()
        label.position = CGPoint(x: self.frame.width/2.0, y: self.size.height/2.0)
        self.addChild(label)
    }
    
    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
        changeSceneDelegate.changeScene(self)
    }
}
```
・結果画面

```lang:ResultScene.swift
import Foundation
import SpriteKit

class ResultScene: SKScene {
    
    var changeSceneDelegate: ChangeSceneProtocol!
    
    override func didMoveToView(view: SKView) {
        
        self.backgroundColor = UIColor.greenColor()
        
        println("ResultScene")
        
        let label = SKLabelNode()
        label.text = "Result Scene"
        label.fontSize = 50
        label.fontColor = UIColor.blackColor()
        label.position = CGPoint(x: self.frame.width/2.0, y: self.size.height/2.0)
        self.addChild(label)
    }
    
    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
        changeSceneDelegate.changeScene(self)
    }
}
```
・画面遷移プロトコル

```lang:ChangeSceneProtocol.swift
import Foundation
import SpriteKit

protocol ChangeSceneProtocol {
    func changeScene(scene: SKScene)
}
```
・シーンを表示するビュー

```lang:GameView.swift
import Foundation
import SpriteKit

class GameView: SKView, ChangeSceneProtocol{
    override init(frame: CGRect) {
        super.init(frame: frame)
        setUpGameView()
    }

    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    //初期画面を設定
    func setUpGameView() {
        switchingTitleScene()
    }
    
    //タイトルシーンへ切り替え
    func switchingTitleScene() {
        let scene = SceneManager.titleScene(self.bounds.size)
        scene.changeSceneDelegate = self
        SceneManager.changeScene(self, New: scene, Duration: 0.5)
    }
    
    //ゲームシーンへ切り替え
    func switchingGamaScene() {
        let scene = SceneManager.gameScene(self.bounds.size)
        scene.changeSceneDelegate = self
        SceneManager.changeScene(self, New: scene, Duration: 0.5)
    }
    
    //結果画面へ移動
    func switchingResultScene() {
        let scene = SceneManager.resultScene(self.bounds.size)
        scene.changeSceneDelegate = self
        SceneManager.changeScene(self, New: scene, Duration: 0.5)
    }
    
    //デリゲートメソッド
    func changeScene(scene: SKScene) {
        if scene.isKindOfClass(TitleScene) {
            switchingGamaScene()
        } else if scene.isKindOfClass(GameScene) {
            switchingResultScene()
        } else if scene.isKindOfClass(ResultScene) {
            switchingTitleScene()
        }
    }
}
```