所以我找不到适合我问题的好答案。我正在iOS上创建SpriteKit游戏。我只是要给大家快速了解我的设置,然后再解决问题。我认为这是最好的解释方式。
基本上,在我的didMove(查看)方法中,我调用了两个帮助器函数:setupNodes()和setupLevel()。这些功能的作用是将不同的场景和SKSpriteNodes加载到内存中,然后将它们添加到场景中。这是我用来执行此操作的代码:
func setupNodes(){
doubleVent = (loadForegroundOverlayTemplate("DoubleVent").copy() as! SKSpriteNode)
}
func loadForegroundOverlayTemplate(_ fileName: String) -> SKSpriteNode{
let overlayScene = SKScene(fileNamed: fileName)!
let overlayTemplate = overlayScene.childNode(withName: "ForegroundOverlay")!.copy() as! SKSpriteNode
return overlayTemplate
}
现在它存储场景,该场景是名为“ ForegroundOverlay”的SKNode的子级。然后,我将其传递给名为“ createForegroundOverlay()”的函数,如下所示:
let overlaySprite = doubleVent
createForegroundOverlay(doubleVent)
然后“ createForegroundOverlay”将存储在doubleVent中的SKSpriteNode添加到场景中,如下所示:
func createForegroundOverlay(_ overlayTemplate: SKSpriteNode) {
let foregroundOverlay = overlayTemplate.copy() as? SKSpriteNode
lastOverlayPosition.x = lastOverlayPosition.x + (lastOverlayWidth + ((foregroundOverlay?.size.width)!)/2)
lastOverlayWidth = (foregroundOverlay?.size.width)!/2.0
foregroundOverlay?.position = lastOverlayPosition
//TESTING PURPOSES
if TESTING_NODE_POS{
print("The last overlay position x:\(lastOverlayPosition.x), y:\(lastOverlayPosition.y)")
print("The last overlay width is \(lastOverlayWidth)")
print("Adding a foreground overlay \(count)")
count += 1
}
//TESTING PURPOSES
if TESTING_BOX_OUTLINE {
let foregroundPos = foregroundOverlay?.position
let boxLocation = foregroundOverlay?.childNode(withName: "Box1")?.position
if boxLocation != nil {
print("The location of the box \(String(describing: boxLocation))")
print("The foregroundLocation is \(String(describing: foregroundPos))")
print("last overlay position is \(lastOverlayPosition)")
}
}
//add the foreground overlay as a child of the foreground node
fgNode.addChild(foregroundOverlay!)
}
用于定位的变量-lastOverlayPosition,lastOverlayWidth等-只是我的GameScene类的属性,用于了解在何时何地添加所传递的叠加层。
fgNode是我从GameScene.sks文件中存储的节点,如下所示:
let worldNode = self.childNode(withName: "World")!
bgNode = worldNode.childNode(withName: "Background")!
bgCityNode = worldNode.childNode(withName: "BackgroundCity")
cityBGOverlayTemplate = (bgCityNode.childNode(withName: "Overlay")!.copy() as! SKNode)
cityOverlayWidth = bgCityNode.calculateAccumulatedFrame().width
backgroundOverlayTemplate = (bgNode.childNode(withName: "Overlay")!.copy() as! SKNode)
backgroundOverlayWidth = backgroundOverlayTemplate.calculateAccumulatedFrame().width
fgNode = worldNode.childNode(withName: "Foreground")!
这也是在我的setupNodes()方法中完成的。
所以也许你们中的一些人已经看到了问题,但是问题是当我启动游戏时它崩溃了,并且我得到了消息:
“线程1:EXC_BAD_ACCESS :(代码= 1,地址= 0x78)”
每当发生崩溃时,它都是完全相同的消息。我想我知道错误在说什么。基本上,有一个指针指向内存中的某个位置(0x78),那里没有任何内容。因此,取消引用该指针显然会导致错误。这是我感到困惑的地方...这只会发生大约50%的时间。当我运行并构建项目时,它每次都会成功构建,然后崩溃50%的时间并显示该错误消息。其次,这在一开始就发生了。这对我来说很奇怪,因为如何可以释放一些内存,导致游戏一开始出现错误的指针。另外,如果崩溃不是在启动时发生的,那么崩溃就永远不会发生,除非在显示游戏结束场景之后我重新加载场景,这与正在重新启动的游戏基本相同。
一段时间后,我将问题缩小为一行代码:
fgNode.addChild(foregroundOverlay!)
如果我将这一行注释掉,则不会发生崩溃(我尝试构建并运行50次)。问题一定出在前景色变量上,该变量是使用本讨论的“设置”部分中的代码设置的。所以我不知道如何解决这个问题...任何想法?
P.S。可能还值得注意的是,以这种方式将孩子添加到场景中时,仅当我升级到xCode 10.0并考虑使用僵尸时才成为一个问题,但我认为这样做没有帮助,因为崩溃仅发生在游戏的发布。
如果我不清楚在任何地方,请告诉我。