let scene = GameScene(size: self.size) scene.scaleMode = .aspectFill let animation = SKTransition.fade(withDuration: 1.0) self.view?.presentScene(scene,transition: animation) self.removeAllChildren() self.removeAllActions() self.scene?.removeFromParent()
1.编辑:我意识到为什么我会收到这个警告:“我正在尝试将节点添加到已经拥有父节点的父节点”,因为我拥有类外部场景的所有变量以及全局变量.但是,现在当游戏重新开始时,游戏就在左下角.为什么会这样,我该如何解决这个问题呢? – 固定
2.Edited:现在一切正常,但现在我担心的是即使删除了每个节点并且fps不会随着时间的推移而丢失,也不会调用deinit {}.这是我在GameViewController中用于设置场景和我的GameScene中的内容(每个与场景相关的实例基本上都是相关的):
import UIKit import SpriteKit import GameplayKit var screenSize = CGSize() class GameViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() if let view = self.view as! SKView? { // Load the SKScene from 'GameScene.sks' if let scene = SKScene(fileNamed: "GameScene") { // Set the scale mode to scale to fit the window scene.scaleMode = .aspectFill screenSize = scene.size // Present the scene view.presentScene(scene) } view.ignoresSiblingOrder = true view.showsFPS = true view.showsNodeCount = true } }
然后我的GameScene基本上是:
import SpriteKit import GameplayKit class GameScene: SKScene,SKPhysicsContactDelegate { //Declare and initialise variables and enumerations here deinit{print("GameScene deinited")} override func didMove(to view: SKView) { //Setup scene and nodes } override func touchesBegan(_ touches: Set<UITouch>,with event: UIEvent?) { //Do other things depending on when and where you touch //When I want to reset the GameScene let newScene = GameScene(size: self.size) newScene.anchorPoint = CGPoint(x: 0.5,y: 0.5) newScene.scaleMode = self.scaleMode let animation = SKTransition.fade(withDuration: 1.0) self.view?.presentScene(newScene,transition: animation) }
任何答案将不胜感激:)
您只需要随时再次呈现一个新的相同场景.所以,你做得很好.
可能的泄漏问题?
此外,如果你的游戏中没有泄漏,意味着没有强大的参考周期,你甚至不需要self.removeAllChildren()和self.removeAllActions()……当然如果你明确想要在转换之前停止动作动画开始,使用这种方法是有道理的.关键是,当场景解除分配时,依赖于它的所有对象也应该/将要解除分配.
不过,如果你从一开始就不知道你在做什么以及如何防止泄漏,例如.你在块中使用强自我,这是一个动作序列的一部分,它永远重复,然后你肯定有一个泄漏,self.removeAllActions()可能会有所帮助(在很多情况下,但它不是一个最终的解决方案).我建议一般阅读有关捕获列表和ARC的内容,因为了解这些情况是如何工作的.
场景是根节点
在场景上调用removeFromParent()无效.场景是根节点,因此无法在当前上下文中删除它.如果你检查场景的父属性,你会发现它是零.当然可以将场景添加到另一个场景,但是在这种情况下,作为子场添加的场景将充当普通节点.
最后,如何呈现新场景?容易,像这样:
override func touchesBegan(_ touches: Set<UITouch>,with event: UIEvent?) { let newScene = GameScene(size: self.size) newScene.scaleMode = self.scaleMode let animation = SKTransition.fade(withDuration: 1.0) self.view?.presentScene(newScene,transition: animation) }
如果某些内容对您不起作用,则可能是您有泄漏(意味着您的场景未被释放).要检查这一点,在GameScene中的某处覆盖deinit方法,如下所示:
deinit{print("GameScene deinited")}
为了进一步向你解释……应该发生的是你应该呈现一个新场景,应该发生转换,应该取消分配旧场景,你应该看到一个具有初始状态的新场景.