Sprite Kit游戏在tvos9.1和iOS 9.2上崩溃

时间:2023-01-23 07:49:15

I have a Sprite Kit game that is crashing when the game is over. This happening on the tvOS 9.1 and iOS 9.2. Before, I had it running on iOS 9.1 without crashing.

我有一个精灵套装游戏,当游戏结束时就崩溃了。这发生在tvos9.1和iOS 9.2上。之前,我在ios9.1上运行过它,但没有崩溃。

It seems to be an OpenGL issue, but when I search the function in Xcode, it doesn't come up with anything.

这似乎是一个OpenGL问题,但是当我在Xcode中搜索这个函数时,它什么都没有。

Unfortunately, the error is not consistent in appearing in the console. Here's the error:

不幸的是,出现在控制台中的错误并不一致。这是一个错误:

Jet: draw_indexed: indexType must be 'unsigned_int' or 'unsigned_short'
Assertion failed: (indexType == jet_component_type_unsigned_int || indexType
== jet_component_type_unsigned_short), function draw_indexed, file
/BuildRoot/Library/Caches/com.apple.xbs/Sources/Jet_Sim/Jet- 
1.50.1/Jet/jet_context_OpenGL.mm, line 1426.

Xcode also points to the AppDelate class when it crashes:

Xcode还指出了它崩溃时的AppDelate类:

class AppDelegate: UIResponder, UIApplicationDelegate

类AppDelegate:UIResponder,UIApplicationDelegate

Sprite Kit游戏在tvos9.1和iOS 9.2上崩溃

With breakpoint exception enabled, Xcode points to this line. It's a constant for a sound file:

启用了断点异常后,Xcode指向这一行。这是一个声音文件的常数:

 let soundHitLava = SKAction.playSoundFileNamed("DrownFireBug.mp3",
waitForCompletion: false)

More info from the exception breakpoint:

更多来自异常断点的信息:

SpriteKit`+[SKAction(SKActions) playSoundFileNamed:waitForCompletion:]:
  0x10b95e738 <+0>:  pushq  %rbp
  0x10b95e739 <+1>:  movq   %rsp, %rbp
  0x10b95e73c <+4>:  movq   0x15bf8d(%rip), %rdi      ; (void   *)0x000000010babd020: SKPlaySound
  0x10b95e743 <+11>: movq   0x1618b6(%rip), %rax      ; (void   *)0x000000010b412be8: CGPointZero
  0x10b95e74a <+18>: movsd  (%rax), %xmm0
  0x10b95e74e <+22>: movsd  0x8(%rax), %xmm1
  0x10b95e753 <+27>: movq   0x159a46(%rip), %rsi      ; "playSoundFileNamed:atPosition:waitForCompletion:"
  0x10b95e75a <+34>: movzbl %cl, %ecx
  0x10b95e75d <+37>: callq  *0x1619a5(%rip)           ; (void *)0x000000010d09e800: objc_msgSend
  0x10b95e763 <+43>: movq   %rax, %rdi
  0x10b95e766 <+46>: callq  0x10ba192e8               ; symbol stub for:   objc_retainAutoreleasedReturnValue
  0x10b95e76b <+51>: movq   %rax, %rdi  // **Thread 1: Breakpoint 1.2
  0x10b95e76e <+54>: popq   %rbp
  0x10b95e76f <+55>: jmp    0x10ba1929a               ; symbol stub for:   objc_autoreleaseReturnValue

Here's the GameOver function in the GameScene:

这是GameScene中的GameOver函数:

 override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {

    #if os(tvOS) // tvOS
    if startTouchX == 0.0 {
        startTouchX = (touches.first?.locationInNode(self).x)!
    }
    #endif

   switch gameState.currentState {
    case is WaitingForTap:
    gameState.enterState(WaitingForBomb)
    // Switch to playing state
    self.runAction(SKAction.waitForDuration(2.0),
      completion:{
      self.gameState.enterState(Playing)
    })

    case is GameOver:
     let newScene = GameScene(fileNamed:"GameScene")
     newScene!.scaleMode = .AspectFill
     let reveal = SKTransition.flipHorizontalWithDuration(0.5)
     self.view?.presentScene(newScene!, transition: reveal)

     self.saveHighScore("com.prismstudios.jumpingcarl.leaderboard", score: GameState.sharedInstance.highScore)

     GameState.sharedInstance.highScore = 0
     GameState.sharedInstance.coins = 0

     default:
       break
     }
    }

And here is the GameOver class:

这是GameOver类:

import SpriteKit
import GameplayKit

class GameOver: GKState {
  unowned let scene: GameScene

init(scene: SKScene) {
self.scene = scene as! GameScene
super.init()
}

override func didEnterWithPreviousState(previousState: GKState?) {
if previousState is Playing {

  scene.playBackgroundMusic("SpaceGame.caf")
  let gameOver = SKSpriteNode(imageNamed: "GameOver")
  gameOver.position = scene.getCameraPosition()
  gameOver.zPosition = 10
  scene.addChild(gameOver)

  let explosion = scene.explosion(6.0)
  explosion.position = gameOver.position
  explosion.zPosition = 11
  scene.addChild(explosion)
  scene.runAction(scene.soundExplosions[3])
  scene.screenShakeByAmt(200)

  scene.addChild(button)
   }
 }

 override func isValidNextState(stateClass: AnyClass) -> Bool {
   return stateClass is WaitingForTap.Type
 }
}

1 个解决方案

#1


1  

The answer I found out was to lower the SKEmitterNode birthrate and particles to emit as this would cause the game to crash.

我发现的答案是降低SKEmitterNode出生率和粒子发射,因为这会导致游戏崩溃。

In the GameScene.swift:

GameScene.swift:

func explosion(intensity: CGFloat) -> SKEmitterNode {
   let emitter = SKEmitterNode()
   let particleTexture = SKTexture(imageNamed: "spark")

   emitter.zPosition = 2
   emitter.particleTexture = particleTexture

   //LOWER the particleBirthRate and numParticlesToEmit
   emitter.particleBirthRate = 50; //4000 * intensity
   emitter.numParticlesToEmit = 50; //Int(400 * intensity)

   ....
 }

Once lowered to 50 respectively, then the game wouldn't crash. I don't know why this is happening, but Apple is currently working on this and is considered a bug.

一旦分别降到50,游戏就不会崩溃。我不知道为什么会发生这种情况,但苹果目前正在研究这个问题,并被认为是一个bug。

#1


1  

The answer I found out was to lower the SKEmitterNode birthrate and particles to emit as this would cause the game to crash.

我发现的答案是降低SKEmitterNode出生率和粒子发射,因为这会导致游戏崩溃。

In the GameScene.swift:

GameScene.swift:

func explosion(intensity: CGFloat) -> SKEmitterNode {
   let emitter = SKEmitterNode()
   let particleTexture = SKTexture(imageNamed: "spark")

   emitter.zPosition = 2
   emitter.particleTexture = particleTexture

   //LOWER the particleBirthRate and numParticlesToEmit
   emitter.particleBirthRate = 50; //4000 * intensity
   emitter.numParticlesToEmit = 50; //Int(400 * intensity)

   ....
 }

Once lowered to 50 respectively, then the game wouldn't crash. I don't know why this is happening, but Apple is currently working on this and is considered a bug.

一旦分别降到50,游戏就不会崩溃。我不知道为什么会发生这种情况,但苹果目前正在研究这个问题,并被认为是一个bug。