初めて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とほとんど同じ
--