Swift:在转换到新场景后取消分配游戏场景



所以我读过几个关于这个的问题,但大多数都在Objective-C中,我还没有找到任何直接的地址/答案。我是这里编程的新手,所以请彻底解释任何建议。

我需要了解如何在游戏结束后解除分配我的游戏场景。我需要这样做的原因是,在游戏结束后,我转换到一个新的SKScene(游戏结束场景),当我转换回我的游戏场景时,要么游戏场景没有完全重置,要么我每次都生成一个新游戏场景。

我这么说是因为每次我结束游戏并转换回游戏场景时,我的每秒帧数都会下降,所以如果我做的次数足够多,我甚至不能再玩游戏了。这是个问题。

我不明白为什么会发生这种情况,因为当我过渡到游戏切换场景时,我会从我的游戏场景中删除所有内容:

self.viewController!.performSegueWithIdentifier("goToGameOver", sender: nil)
            self.removeAllChildren()
            self.removeAllActions()
            self.scene?.removeFromParent()

我也在这里读到:关闭SKScene后,内存仍然很高,删除包含SKScene的SKView会取消分配SKScene,所以当我的游戏场景和游戏结束场景都剩下时,我会从它们的超视图中删除这两个视图,如下所示:

override func viewDidDisappear(animated: Bool) {
        print("its gone")
        self.view.removeFromSuperview()
    }

但没有任何东西会影响每秒帧数的下降,游戏一直处于滞后状态。我不明白我没有做什么,也不知道是场景外的游戏是问题所在,还是我只是没有释放GameScene。

如何解除分配游戏场景?我还应该做什么?

编辑:

每次我转换回GameScene时,我的节点数和平局数都保持不变,所以这似乎不是问题。我尝试在GameScene类中使用这个测试在场景之间转换时是否调用了deinit(我以前没有deinit

} //<**End of GAMESCENE**
    deinit {
        print("Deinit was called")
    } 

并且没有打印任何内容,因此不会调用deinit

编辑2:

@alex_p这是我的GameViewController-中的内容

class GameViewController: UIViewController, SKProductsRequestDelegate, SKPaymentTransactionObserver {
    var scene1: GameScene?
    var scene2: GameScene?
    var skView: SKView?
// Action to present next Scene
    @IBAction func nextSceneAction(sender: AnyObject) {
        print("Next scene")
        // Create new GameScene object
        scene2 = GameScene(fileNamed:"GameScene")
        // Present scene2 object that replace the scene1 object
        skView!.presentScene(scene2) //ERROR ON THIS LINE
        scene1 = nil
    }

我在GameScene中这样调用这个方法:

self.viewController.nextSceneAction(self)

我完全复制了你的,但我在上面评论的行上收到了错误unexpectedly found nil while unwrapping an Optional value。不被召唤是愚蠢的。

在我的项目中,我使用了以下机制,并且运行良好。我的所有场景SKScene对象都是可选变量。当我需要显示新场景时,我会创建它并在SKView中显示。当我需要显示新场景时,我将上一个对象场景对象设置为nil,这会立即将引用计数减少1,因为此时没有一个对象不使用我的场景,引用计数变为零,场景被删除。

SKScene对象是一个普通的类对象,ARC与它们一起工作,就像与所有引用类型对象一样。您只需要监视对场景的引用数量。我在SKScene对象的deinit中启动的各种资源都完成了

简单的例子:

UIViewController,我们有GameScene的可选对象:

class GameViewController: UIViewController {
    var scene1: GameScene?
    var scene2: GameScene?
    var skView: SKView?
    
    // Action to present next Scene
    @IBAction func nextSceneAction(sender: AnyObject) {
        print("Next scene")
        // Create new GameScene object
        scene2 = GameScene(fileNamed:"GameScene")
        // Present scene2 object that replace the scene1 object
        skView!.presentScene(scene2)
        scene = nil
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Create GameScene object
        scene = GameScene(fileNamed:"GameScene")
        skView = (self.view as! SKView)
        skView!.showsFPS = true
        skView!.showsNodeCount = true
        skView!.ignoresSiblingOrder = true
        
        scene!.scaleMode = .AspectFill
        
        // Present current scene
        skView!.presentScene(scene)
    }
}

deinit中的GameScene处,打印一些文本以显示其对象将被删除:

class GameScene: SKScene {
   ...
    
    deinit {
        print("Deinit scene")
    }
}

按下nextSceneAction按钮后调试输出:

下一个场景

Deinit场景

最新更新