Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

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

--

sa-k0
たまになにかかきます
https://biwanoie.tokyo
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away