首页 > 解决方案 > 当我制作 2 个场景时,由于未捕获的异常而终止应用程序

问题描述

我正在尝试在我的迷宫游戏中创建 2 个场景,这是我收到的错误消息。我的任何 SKS 文件中都没有带有这些坐标的精灵,所以我很困惑它不能加载什么物理体......

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)

另外,这是我的游戏场景文件代码和我的游戏场景2文件代码:

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
    }
}

(这里是游戏场景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
    }
}

标签: swiftsprite-kitcrashlldbskphysicsbody

解决方案


在您的游戏场景文件中,您正在创建和呈现一个GameScene2对象:

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

然后,在您的Gamescene2didMove(to view: SKView)方法中,您将再次添加相同的场景:

let gameScene2 = SKScene(fileNamed: "GameScene2")

self.addChild(gameScene2!)

这就是崩溃发生的地方。您可以从堆栈跟踪中看到,您自己代码中的最后一个调用是在didMove(to...)方法中(它的名称被编译器弄错了,但是下面的第 6 行):

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

从上面的第 5 行可以看出,addChildSpriteKit 中的后续调用最终会导致崩溃。


推荐阅读