2016-05-06 7 views
0

現在、SpriteKitを使用してiOS用のゲームを行っています。テクスチャアトラスのプリロードを実装しているときに奇妙なクラッシュが発生しました。ここで私はこれまで得たものの迅速な概要です:SpriteKit:テクスチャアトラスをプリロードするときに奇妙なクラッシュが発生する

GameViewController.swift

import UIKit 
import SpriteKit 

class GameViewController: UIViewController { 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     // Configure the view. 
     let skView = self.view as! SKView 
     skView.showsFPS = true 
     skView.showsNodeCount = true 
     skView.showsDrawCount = true 
     skView.showsPhysics = false 
     skView.ignoresSiblingOrder = true 
     skView.multipleTouchEnabled = true 

     // Setup scene 
     let scene = GameScene(size: skView.bounds.size) 
     scene.scaleMode = .ResizeFill 

     let MyAtlas1 = SKTextureAtlas(named: "MyAtlas1") 
     let MyAtlas2 = SKTextureAtlas(named: "MyAtlas2") 
     let MyAtlas3 = SKTextureAtlas(named: "MyAtlas3") 

     SKTextureAtlas.preloadTextureAtlases([MyAtlas1, MyAtlas2, MyAtlas3], withCompletionHandler: 
     { 
      print("Everything loaded!") 

      // Present scene 
      skView.presentScene(scene) 
     }) 
    } 
    [...] 

GameScene.swift

import SpriteKit 

class GameScene: SKScene { 

    var cam: SKCameraNode! 
    var tilemap: Tilemap! 
    var previousTime: CFTimeInterval = 0 
    [...] 

    override func didMoveToView(view: SKView) { 
     /* Setup your scene here */ 

     [...] 

     // Setup camera 
     self.cam = SKCameraNode() 
     self.cam.setScale(self.camScaleFactor) 
     self.camera = self.cam 
     self.addChild(self.cam) 

     [...] 

     // Load Tilemap 
     self.tilemap = Tilemap(mapName: "testlevel2") 
     self.addChild(self.tilemap) 

     // Setup UI 
     [...] 
    } 

    [...] 

    override func update(currentTime: CFTimeInterval) { 
     /* Called before each frame is rendered */ 

     if self.previousTime == 0 { 
      self.previousTime = currentTime 
     } 

     let delta = currentTime - self.previousTime 

     var p = self.cam.position 
     p.x += 2.0 * CGFloat(delta) 
     p.y += 1.5 * CGFloat(delta) 
     self.cam.position = p 

     // Update tilemap 
     self.tilemap.update(delta) 

     self.previousTime = currentTime 
    } 
} 

didMoveToView機能はそれとして、少し長いですカメラ、タイルマップ、UIスタッフ、およびいくつかの制約を初期化します。しかし、これはうまくコンパイルされます。しかし、私がゲームを実行すると、すぐに次の致命的なエラーでクラッシュします。「オプション値をアンラッピングしている間に予期せず見つからない」それは、(ランダムに)任意の値であることが、判明self.tilemap又はself.camとエラーは、次の行のいずれかにGameSceneの更新()関数(また、ランダムに)に起こるような:

// here 
var p = self.cam.position 

// or here 
self.tilemap.update(delta) 

デバッガは、self.tilemapまたはself.camがnilであることを通知します。しかし、私はなぜそれが当てはまるのか理解できません。シーンが表示されてから途中で突然途切れると、関数didMoveToViewが実行され、self.tilemapまたはself.camがまだ初期化されていないupdate関数が呼び出されます。

私はこれにGameViewControllerののviewDidLoad機能を変更します。

override func viewDidLoad() { 
     super.viewDidLoad() 

     // Configure the view. 
     let skView = self.view as! SKView 
     skView.showsFPS = true 
     skView.showsNodeCount = true 
     skView.showsDrawCount = true 
     skView.showsPhysics = false 
     skView.ignoresSiblingOrder = true 
     skView.multipleTouchEnabled = true 

     // Setup scene 
     let scene = GameScene(size: skView.bounds.size) 
     scene.scaleMode = .ResizeFill 

     let MyAtlas1 = SKTextureAtlas(named: "MyAtlas1") 
     let MyAtlas2 = SKTextureAtlas(named: "MyAtlas2") 
     let MyAtlas3 = SKTextureAtlas(named: "MyAtlas3") 

     SKTextureAtlas.preloadTextureAtlases([MyAtlas1, MyAtlas2, MyAtlas3], withCompletionHandler: 
     { 
      print("Everything loaded!")     
     }) 

     // Present scene 
     skView.presentScene(scene) 
    } 
    [...] 

すべてが完璧に動作します。しかし、それは明らかに解決策ではありません。を事前にロードしてから、のシーンを開始します。また注意してください:プリロードされたアトラスは、私がそれらを強く参照していないので、すぐにメモリから削除されることを認識しています。とにかく、そのコードはデモンストレーションとテストのためのものです。

私の質問は次のとおりです。誰も似たような問題を抱えていたことがありますか、そのエラーで何が起こっているのですか?私は何が間違っているのか分かりません。どんな助けも大歓迎です。

+0

コンソールを見ると、推測されていないように変数が何であるかがわかります。また、なぜあなたのアトラスをView Controllerにロードしていますか?GameScene – Knight0fDragon

+0

私は推測しませんでした。私が言ったように、それは無作為にself.tilemapかself.camです。 ViewControllerで読み込むのではなく、GameSceneの読み込みの利点は何ですか? – snorge

+0

コードの読みやすさ、Viewコントローラはアトラスについて何も知ってはいけません、GameSceneはそうしていますので、6ヶ月後にこのコードをバックアップすると、あなたはそれらのアトラスをどこに置くのか不思議ではありません。そして、コードはdidMoveToViewを終了することなくランダムに更新することはできません。同じスレッド上にあるので、わからないコードで何かが起きています – Knight0fDragon

答えて

0

attach image ho setup SKView for UIView

あなたは、テンプレートを使用してアプリケーションを作成し、それがSCNViewとしてビューを作成します。 このSCNViewは、ストーリーボードSKViewに持っていたいと闘っています。

  1. あなたは
  2. SKViewは、それがリスト
  3. 上でなくても受け入れます
  4. は、プロパティクラス、タイプSKView
  5. をストーリーボード正規UIViewを入力し表示オプションとして使用できません絵コンテからSCNViewを削除します。
  6. 作成時に問題が解決されますSKView

添付画像をご覧ください。

関連する問題