Search code examples
swiftsprite-kitcrashlldbskphysicsbody

Terminating app due to uncaught exception when I make 2 scenes


I am trying to create 2 scenes in my maze game and this is the error message that I get. There is no sprite in any of my SKS files with these coordinates, so I am very confused as to what physics body it cannot load...

mazeGame[18879:890324] *** Terminating app due to uncaught exception 'Cant add body, already exists in a world', reason: 'Cant add body <SKPhysicsBody> type:<Rectangle> representedObject:[<SKScene> name:'gameScene2' frame:{{-375, -667}, {750, 1334}} anchor:{0.5, 0.5}], already exists in a world'
*** First throw call stack:
(
    0   CoreFoundation                      0x00000001107041e6 __exceptionPreprocess + 294
    1   libobjc.A.dylib                     0x000000010c64b031 objc_exception_throw + 48
    2   CoreFoundation                      0x0000000110779975 +[NSException raise:format:] + 197
    3   PhysicsKit                          0x000000011709585b -[PKPhysicsWorld addBody:] + 87
    4   SpriteKit                           0x000000010d0af05d -[SKNode insertChild:atIndex:] + 468
    5   SpriteKit                           0x000000010d0aee68 -[SKNode addChild:] + 68
    6   mazeGame                            0x000000010bd3526b _T08mazeGame0B6Scene2C7didMoveySo6SKViewC2to_tF + 379
    7   mazeGame                            0x000000010bd35c6c _T08mazeGame0B6Scene2C7didMoveySo6SKViewC2to_tFTo + 60
    8   SpriteKit                           0x000000010d075edf -[SKScene _didMoveToView:] + 173
    9   SpriteKit                           0x000000010d0962f2 -[SKView presentScene:transition:] + 347
    10  mazeGame                            0x000000010bd340e7 _T08mazeGame0B5SceneC8didBeginySo16SKPhysicsContactCF + 839
    11  mazeGame                            0x000000010bd3423c _T08mazeGame0B5SceneC8didBeginySo16SKPhysicsContactCFTo + 60
    12  PhysicsKit                          0x0000000117099a17 _ZN17PKContactListener13flushContactsEv + 571
    13  PhysicsKit                          0x00000001170975d6 -[PKPhysicsWorld stepWithTime:velocityIterations:positionIterations:] + 224
    14  SpriteKit                           0x000000010d076c3d -[SKScene _update:] + 3208
    15  SpriteKit                           0x000000010d096a21 -[SKView _update:] + 969
    16  SpriteKit                           0x000000010d0932db __51-[SKView _vsyncRenderForTime:preRender:postRender:]_block_invoke.316 + 281
    17  SpriteKit                           0x000000010d0926ef -[SKView _vsyncRenderForTime:preRender:postRender:] + 527
    18  SpriteKit                           0x000000010d093f91 __29-[SKView setUpRenderCallback]_block_invoke + 211
    19  SpriteKit                           0x000000010d0d79ea -[SKDisplayLink _callbackForNextFrame:] + 335
    20  QuartzCore                          0x0000000114d31850 _ZN2CA7Display11DisplayLink14dispatch_itemsEyyy + 834
    21  QuartzCore                          0x0000000114e73a12 _ZL22display_timer_callbackP12__CFMachPortPvlS1_ + 248
    22  CoreFoundation                      0x00000001106934b9 __CFMachPortPerform + 169
    23  CoreFoundation                      0x00000001106933f9 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 41
    24  CoreFoundation                      0x0000000110693361 __CFRunLoopDoSource1 + 465
    25  CoreFoundation                      0x000000011068af64 __CFRunLoopRun + 2532
    26  CoreFoundation                      0x000000011068a30b CFRunLoopRunSpecific + 635
    27  GraphicsServices                    0x0000000112a78a73 GSEventRunModal + 62
    28  UIKit                               0x000000010d2a0057 UIApplicationMain + 159
    29  mazeGame                            0x000000010bd380b7 main + 55
    30  libdyld.dylib                       0x00000001118e5955 start + 1
    31  ???                                 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)

Also, here is my gamescene file code and my gamescene2 file code:

import SpriteKit
import GameplayKit
import CoreMotion

class GameScene: SKScene, SKPhysicsContactDelegate{

    let gameScene = SKScene()

    var playerSprite = SKSpriteNode()
    var nextNode = SKSpriteNode()

    let motionManager = CMMotionManager()

    override func didMove(to view: SKView) {

        self.physicsWorld.contactDelegate = self

        playerSprite = self.childNode(withName: "playerSprite") as! SKSpriteNode
        nextNode = self.childNode(withName: "nextNode") as! SKSpriteNode

        motionManager.startAccelerometerUpdates()
        motionManager.accelerometerUpdateInterval = 0.1
        motionManager.startAccelerometerUpdates(to: OperationQueue.main) {
            (data,error) in

            self.physicsWorld.gravity = CGVector(dx: CGFloat((data?.acceleration.x)!) * 10, dy: CGFloat((data?.acceleration.y)!) * 10)
        }
    }

    func didBegin(_ contact: SKPhysicsContact) {
        let bodyA = contact.bodyA
        let bodyB = contact.bodyB

        if bodyA.categoryBitMask == 1 && bodyB.categoryBitMask == 2 || bodyA.categoryBitMask == 2 && bodyB.categoryBitMask == 1{

            let transition = SKTransition.fade(withDuration: 0.5)
            let gameScene2 = GameScene2(size: self.size)
            self.view?.presentScene(gameScene2, transition: transition)
            playerSprite.removeFromParent()
            nextNode.removeFromParent()
        }
    }
    override func update(_ currentTime: TimeInterval) {
        // Called before each frame is rendered
    }
}

(here is the gamescene 2)

import SpriteKit
import GameplayKit
import CoreMotion
import SceneKit

class GameScene2: SKScene, SKPhysicsContactDelegate{

    let motionManager = CMMotionManager()

    var playerSprite2 = SKSpriteNode()
    var nextNode2 = SKSpriteNode()

    override func didMove(to view: SKView) {

        let gameScene2 = SKScene(fileNamed: "GameScene2")

        self.addChild(gameScene2!)

        self.physicsWorld.contactDelegate = self

        playerSprite2 = self.childNode(withName: "playerSprite2") as! SKSpriteNode
        nextNode2 = self.childNode(withName: "nextNode2") as! SKSpriteNode

        playerSprite2.physicsBody = nil
        nextNode2.physicsBody = nil

        motionManager.startAccelerometerUpdates()
        motionManager.accelerometerUpdateInterval = 0.1
        motionManager.startAccelerometerUpdates(to: OperationQueue.main) {
            (data,error) in

            self.physicsWorld.gravity = CGVector(dx: CGFloat((data?.acceleration.x)!) * 10, dy: CGFloat((data?.acceleration.y)!) * 10)
        }
    }

    func didBegin(_ contact: SKPhysicsContact) {
        let bodyA = contact.bodyA
        let bodyB = contact.bodyB

        if bodyA.categoryBitMask == 1 && bodyB.categoryBitMask == 2 || bodyB.categoryBitMask == 2 && bodyA.categoryBitMask == 1{

            print("Yay!!!")
        }
    }
    override func update(_ currentTime: TimeInterval) {
        // Called before each frame is rendered
    }
}

Solution

  • In your game scene file, you are creating and presenting a GameScene2 object:

    let gameScene2 = GameScene2(size: self.size)
    self.view?.presentScene(gameScene2, transition: transition)
    

    Then, in your Gamescene2 class didMove(to view: SKView) method, you are adding the same scene again:

    let gameScene2 = SKScene(fileNamed: "GameScene2")
    
    self.addChild(gameScene2!)
    

    This is where the crash is happening. You can see from the stack trace, the last call in your own code is in the didMove(to...) method (its name is mangled by the compiler, but line 6 below):

    5   SpriteKit                           0x000000010d0aee68 -[SKNode addChild:] + 68
    6   mazeGame                            0x000000010bd3526b _T08mazeGame0B6Scene2C7didMoveySo6SKViewC2to_tF + 379
    

    And you can see from line 5 above, that the subseqent call to addChild in SpriteKit is eventually leading to the crash.