所以我读过几个关于这个的问题,但大多数都在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场景