返回 App SpriteKit 后按播放
Posted
技术标签:
【中文标题】返回 App SpriteKit 后按播放【英文标题】:Pressing play after returning to App SpriteKit 【发布时间】:2016-04-15 21:55:18 【问题描述】:APP DELEGATE 崩溃问题
我是编程的初学者,在开发我的应用程序时,出现了一个无法解决的问题。当用户离开应用程序本身时,我尝试暂停游戏,当需要返回时,游戏暂停,因为按下主页按钮。我的困难是,当用户在游戏未暂停的情况下离开应用程序并返回时,它可以完美运行,但是当用户暂停游戏并离开时,Xcode 向我显示一条错误消息:“线程 1:信号 SIGARBT em>”,游戏就崩溃了。如果你看看我的游戏,我会很高兴的
自行编码
AppDelegate.swift
func applicationWillResignActive(application: UIApplication)
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
//pause when leaving app
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("pauseState"), name: "pauseState", object: nil)
GameScene.swift
import SpriteKit
class GameScene: SKScene, SKPhysicsContactDelegate
var gameLayer = SKNode()
var pauseLayer = SKNode()
var gameStarted = Bool()
var pauseButton = SKSpriteNode()
var playButton = SKSpriteNode()
func setupPauseButton()
//Pause
pauseButton = SKSpriteNode (imageNamed: "pause")
pauseButton.setScale(0.25)
pauseButton.position = CGPoint(x: self.frame.width / 10, y: self.frame.height / 1.5)
//pauseButton.zPosition = 3
func setupPlayButton()
//Play
playButton = SKSpriteNode (imageNamed: "play")
playButton.setScale(0.15)
playButton.position = CGPoint(x: self.frame.width / 10, y: self.frame.height / 1.5)
//playButton.zPosition = 3
//layers
func createGameLayer()
self.physicsWorld.contactDelegate = self
setupPauseButton()
gameLayer.addChild(pauseButton) //add pauseButton to gameLayer
pauseButton.hidden = true
func createPauseLayer()
//Play
setupPlayButton()
pauseLayer.addChild(playButton) //add playButton to pauseLayer
override func didMoveToView(view: SKView)
/* Setup your scene here */
//pause when coming back
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("pauseState"), name: "pauseState", object: nil)
self.addChild(gameLayer)
createGameLayer()
createPauseLayer()
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?)
/* Called when a touch begins */
//run only if game is running
if gameLayer.paused == false
//pauseButton shows when starting to play
pauseButton.hidden = false
//when touch buttons/screen
for touch in touches
let location = touch.locationInNode(self)
let node = nodeAtPoint(location)
if node == pauseButton
pauseState()
else if node == playButton
playState()
else
if gameStarted == false //game didn't start yet
gameStarted = true
Character.physicsBody?.affectedByGravity = true //start falling when touch the screen
//first jump
Character.physicsBody?.velocity = CGVectorMake(0, 0)
Character.physicsBody?.applyImpulse(CGVectorMake(0, 15))
else
//jump
Character.physicsBody?.velocity = CGVectorMake(0, 0)
Character.physicsBody?.applyImpulse(CGVectorMake(0, 15))
//states
func pauseState()
pauseButton.hidden = true //hide pauseButton
self.physicsWorld.speed = 0 //pause physics (character, etc)
gameLayer.paused = true //pause gameLayer
self.addChild(pauseLayer) //add pauseLayer
func playState()
pauseLayer.removeFromParent() //remove pauseLayer
gameLayer.paused = false //unpause gameLayer
self.physicsWorld.speed = 1 //unpause physics (character, etc)
pauseButton.hidden = false //show pauseButton
override func update(currentTime: CFTimeInterval)
/* Called before each frame is rendered */
【问题讨论】:
访问raywenderlich.com/10209/my-app-crashed-now-what-part-1了解如何调试崩溃 【参考方案1】:我在您的代码中注意到的两件事
1) 从 swift 2.2 开始,苹果终于将选择器方法从字符串中更改了。所以在你的 gameScene 中将观察者更改为这个。
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(GameScene.pauseState), name: "pauseState", object: nil)
https://medium.com/swift-programming/swift-selector-syntax-sugar-81c8a8b10df3#.kncj5thdh
2) 在您的应用委托中,您正在添加另一个没有意义的观察者。您想将通知发布给您在 GameScene 中的观察者。
改成这个
NSNotificationCenter.defaultCenter().postNotificationName("pauseState", object: nil)
3) 不确定您是否正在这样做,但始终建议您在离开场景时删除任何 NSNotification 观察者。拨打此行
NSNotificationCenter.defaultCenter().removeObserver(self)
当你过渡到新场景或在 GameScenes 中的“WillMoveFromView”方法中
如果您遵循苹果命名约定,这也是一个好主意。只有类、结构、枚举和协议应该以大写字母开头。这使您的代码对您自己和在 SO 上更具可读性(您的代码标记为蓝色,但不应该)
希望这会有所帮助。
【讨论】:
以上是关于返回 App SpriteKit 后按播放的主要内容,如果未能解决你的问题,请参考以下文章
在不同的 UIKit 和 SpriteKit 场景中连续播放音频