线程 1:SpriteKit 游戏中的信号 SIGABRT 错误

Posted

技术标签:

【中文标题】线程 1:SpriteKit 游戏中的信号 SIGABRT 错误【英文标题】:Thread 1: signal SIGABRT error in SpriteKit game 【发布时间】:2017-06-13 00:15:00 【问题描述】:

这个问题与我之前提出的关于我在 SpriteKit 中制作的 Galaga 游戏的问题有关。 (Cannot assign value of type '[SKNode]' to type 'SKSpriteNode!') 我只是继续我的新问题。

我有一个线程 1 信号:当我尝试在我的游戏中按下启动按钮时,App Delegate 中出现 SIGABRT 错误(启动按钮是一个 SKSpriteNode。)有时它会启动,但只有当我在非常特定的位置点击按钮时才会启动.否则,它会给我 SIGABRT 错误。它可能来自我的touchesBegan 函数中的代码,

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) 

for touch in touches 
    let location = (touch as UITouch).location(in: self)
    let nodes = self.nodes(at: location)
    for node in nodes 
        if node.name == "FireButton" 
            shoot()
         else 
            let touchLocation = touch.location(in: self)
            spaceship.position.x = touchLocation.x
        
     
  

fireLaser 函数,

func fireLaser(laser: SKNode, toDestination destination: CGPoint, withDuration duration: CFTimeInterval, andSoundFileName soundName: String) 
  let laserAction = SKAction.sequence([
    SKAction.move(to: destination, duration: duration),
    SKAction.wait(forDuration: 3.0 / 60.0),
    SKAction.removeFromParent()
  ])

addChild(laser)
laser.run(SKAction.group([laserAction]))

shoot 函数。

func shoot() 
   self.laser.position = CGPoint(x: self.spaceship.position.x, y: 
   self.spaceship.position.y + self.spaceship.frame.height - 
   self.laser.frame.height/2)
   self.addChild(self.laser)
   let laserDestination = CGPoint(x: self.spaceship.position.x, y: 
      self.frame.height + self.laser.frame.height / 2)
      self.fireLaser(laser: self.laser, toDestination: laserDestination, withDuration: 1.0, andSoundFileName: "laser sound effect.mp3")

这是我收到错误时看到的屏幕截图。 [错误截图][1]

此外,当我收到错误消息时,控制台中会显示以下消息,

2017-06-12 17:02:06.100 Galaga Copy[790:23281] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attemped to add a SKNode which already has a parent: <SKSpriteNode> name:'(null)' texture:[<SKTexture> 'Laser' (27 x 150)] position:-5.8244380950927734, -411.53384399414062 scale:1.00, 1.00 size:13.5, 75 anchor:0.5, 0.5 rotation:0.00'

*** 首先抛出调用堆栈: ( 0 核心基础 0x0000000105cfcb0b 异常预处理 + 171 1 libobjc.A.dylib 0x000000010261f141 objc_exception_throw + 48 2 核心基础 0x0000000105d65625 +[NSException raise:format:] + 197 3 SpriteKit 0x0000000103218c95-[SKNode insertChild:atIndex:] + 162 4 SpriteKit 0x0000000103218bd2-[SKNode addChild:] + 68 5 Galaga 复制 0x0000000102036601 _TFC11Galaga_Copy9GameScene5shootfT_T_ + 1089 6 Galaga 复制 0x0000000102036f57 _TFC11Galaga_Copy9GameScene12touchesBeganfTGVs3SetCSo7UITouch_4withGSqCSo7UIEvent__T_ + 1431 7 Galaga 复制 0x0000000102037436 _TToFC11Galaga_Copy9GameScene12touchesBeganfTGVs3SetCSo7UITouch_4withGSqCSo7UIEvent__T_ + 102 8 SpriteKit 0x00000001032007c4-[SKView touchesBegan:withEvent:] + 1130 9 UIKit 0x000000010347154b-[UIWindow_sendTouchesForEvent:] + 2036 10 UIKit 0x0000000103472f00 -[UIWindow 发送事件:] + 4114 11 UIKit 0x000000010341fa84-[UIApplication sendEvent:] + 352 12 UIKit 0x0000000103c035d4 __dispatchPreprocessedEventFromEventQueue + 2926 13 UIKit 0x0000000103bfb532 __handleEventQueue + 1122 14 核心基础 0x0000000105ca2c01 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION + 17 15 核心基础 0x0000000105c880cf __CFRunLoopDoSources0 + 527 16 核心基础 0x0000000105c875ff __CFRunLoopRun + 911 17 核心基础 0x0000000105c87016 CFRunLoopRunSpecific + 406 18 图形服务 0x000000010a159a24 GSEventRunModal + 62 19 UIKit 0x0000000103402134 UIApplicationMain + 159 20 Galaga 副本 0x0000000102039b07 主要 + 55 21 libdyld.dylib 0x0000000106c9c65d 开始 + 1 ) libc++abi.dylib:以 NSException 类型的未捕获异常终止 (lldb)

抱歉,这一切都不正常了,但我不知道如何让它正确显示。谁能帮我解决这个问题?

【问题讨论】:

请您在屏幕右下角添加打印内容的详细信息。 您不止一次添加同一个节点“激光”。您必须每次都创建一个新的激光实例。 我的另一个想法。有谁知道如何让飞船连续开火而无需用户按下开火按钮?这样做会更容易,因为我不需要让事情变得很复杂的按钮。 【参考方案1】:

self.addChild(self.laser)

可能是您的问题。重新分配节点而不将它们从以前的父节点中删除可能会导致此问题。

我建议先.removeFromParent 看看是否可行。我注意到你把它放在了fire() 函数中,但你可能在该块运行之前调用了shoot()

【讨论】:

是的,再次添加激光就是问题所在。应用程序终止时的消息是“尝试添加一个已经有父节点的 SKNode: name:'(null)' texture:[ 'Laser' (27 x 150)] 等。纹理用的是激光,我猜你正在用它来做你的激光节点。

以上是关于线程 1:SpriteKit 游戏中的信号 SIGABRT 错误的主要内容,如果未能解决你的问题,请参考以下文章

在哪里为 SIGPIPE 声明 sig_t 信号

重新启动默认 cosos2d 项目导致“线程 1:信号 SIGBRT 1”错误

pthread中向线程发送信号

Unix系统编程()发送信号的其他方式:raise和killpg

在Java线程的串口调用中没有收到Native SIGIO信号

SpriteKit 游戏中的 AVAudioPlayer 和性能问题