SpriteKitでベースクラスをつくってシーン管理する(Swift)


初めてSwiftのSpriteKitでアプリをつくって、シーン管理どうしようか最初に色々考えてみたのでメモ。
結論でいうと、SKSceneを継承したBaseSceneなるものをつくり、すべてのシーンはBaseSceneを継承することにする。
BaseScene内にシーンの移動処理を書く。

#いいなと思った点

* 実際にいろいろ処理を書くシーンに、シーン切り替え周りでいろいろ書く必要がない
* シーンの切り替えというよりはベースシーンがあることで、ベースシーンにもSKNodeを置いて、どのシーンでも共通して必要なものがまとめて書けた(ヘッダー要素とか)
* BaseSceneでデリゲートなりリスナーを用意することで現在のシーンクラスじゃないところからシーン切り替えができた。
* 最後までアプリつくることができた。

#微妙だと思った点

* 事前に色々調べたがこんなことしてる人いなさそうだった
* SwiftもSpriteKitも初めてなのでベストな方法がよくわかっていないので不安
* シーン数多くなってきたら行数が膨らむのでそれ対策を考えたい


#ファイル構成
--
GameのSpriteKitではなく
Single Veiw Applicationで作成
元からあるものなどは省略

/ViewController.swift
/SceneView.swift
/Scenes/BaseScene.swift
/Scenes/Scene1.swift
/Scenes/Scene2.swift
/Scenes/Scene3.swift
/Scenes/Scene4.swift


#実装例

実際に書いたものから不必要な部分を削っただけなので
どこか足りなくて動かなかったらすみません。


```ViewController.swift
import UIKit
import SpriteKit

class ViewController: UIViewController{
    
    private var sceneView: SceneView?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        sceneView = SceneView(frame: self.view.frame)
        self.view = sceneView   
    }
}

```

```SceneView.swift
 import Foundation
 import SpriteKit
 import EmitterKit
  
 class SceneView: SKView{
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.showsFPS = true
        self.showsNodeCount = true
        self.ignoresSiblingOrder = true
        self.frameInterval = 1
       
        //最初のシーン
        let scene:SKScene!
        
        scene = Scene1(size: self.bounds.size)
        
        scene.scaleMode = SKSceneScaleMode.AspectFill
        self.presentScene(scene)
    }
    
    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
 }
 ```
 
 ```BaseScene.swift
 import Foundation
import SpriteKit

class BaseScene: SKScene {

    override func didMoveToView(view: SKView) {
        //共通nodeとか置ける   
    }

    override func update(currentTime: NSTimeInterval) {
        //どのシーンでも共通してループするものがあれば
    }
    
    //シーンを切り替える関数
    func changeToScene1(){
        let scene = Scene1(size: self.scene!.size)
        scene.scaleMode = SKSceneScaleMode.AspectFill
        self.scene!.view?.presentScene(scene)
    }
    
    func changeToScene2(){
        let scene = Scene2(size: self.scene!.size)
        scene.scaleMode = SKSceneScaleMode.AspectFill
        self.scene!.view?.presentScene(scene)
    }
    
    func changeToScene3(){
        let scene = Scene3(size: self.scene!.size)
        scene.scaleMode = SKSceneScaleMode.AspectFill
        self.scene!.view?.presentScene(scene)
    }
    
    func changeToScene4(){
        let scene = Scene4(size: self.scene!.size)
        scene.scaleMode = SKSceneScaleMode.AspectFill
        self.scene!.view?.presentScene(scene)
    }
    
}
```
 
```Scene1.Swift
import SpriteKit

class Scene1: BaseScene {
       override func didMoveToView(view: SKView) {
        super.didMoveToView(view)
    
       
    }
    
    override func update(currentTime: NSTimeInterval) {
        super.update(currentTime)
        
    }
 
        
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    	super.changeToScene2()
    }
    
        
    deinit{
        print("deinit Scene1")
    }
}
```

Scene2~4はScene1とほとんど同じ


--