前段时间我在didBecomeActive
暂停游戏时出现问题,然后我找到了一个我认为有效的解决方案,直到现在。
我发现当我离开时,iOS会自动暂停我的游戏(所有这些),而不是终止游戏;当回来时(didBecomeActive
),它会取消暂停。我的观点是暂停一个奇异的层(gameLayer
),我创建了一个布尔变量和一个if条件来检查我的游戏是否暂停。
如果checkPause == false
(未暂停) - >当它回到游戏中时(稍后被系统取消暂停?)它会调用一个暂停功能(效果很好)
如果checkPause == true
(暂停) - >它会将gameLayer.paused = false
(由系统取消暂停)设置为true
(在离开游戏之前暂停)
基本上gameLayer
在回来时没有暂停。看起来iOS在didBecomeActive
功能后取消了我的游戏。
我用下面的代码制作了一个示例项目(它的所有评论都是最简单的)
如果需要,您可以下载here。
import SpriteKit
class GameScene: SKScene {
//Declarations
var gameLayer = SKNode()
var pauseLayer = SKNode()
var checkPause = Bool() //checkPause == true -> gameLayer is paused | checkPause == false -> gameLayer is not paused
var enemy = SKSpriteNode()
var pauseButton = SKSpriteNode()
var playButton = SKSpriteNode()
//"Cage" objects in the screen
func cageObjects(){
//"caging" every object
let borderBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
borderBody.friction = 0
self.physicsBody = borderBody
}
//Setup
func setupPauseButton(){
//Pause
pauseButton = SKSpriteNode (imageNamed: "pause")
pauseButton.setScale(1)
pauseButton.position = CGPoint(x: self.frame.width / 2, y: self.frame.height / 1.2)
}
func setupPlayButton(){
//Play
playButton = SKSpriteNode (imageNamed: "play")
playButton.setScale(1)
playButton.position = CGPoint(x: self.frame.width / 2, y: self.frame.height / 1.2)
}
func setupEnemy(){
//Enemy
enemy = SKSpriteNode(imageNamed: "enemy")
enemy.position = CGPointMake(self.frame.width / 1, self.frame.height / 2)
enemy.name = "enemy"
enemy.setScale(0.5)
enemy.physicsBody?.affectedByGravity = false
}
//Layers
func createGameLayer(){
//pauseButton
setupPauseButton()
gameLayer.addChild(pauseButton) //add pauseButton to gameLayer
}
func createPauseLayer(){
//playButton
setupPlayButton()
pauseLayer.addChild(playButton) //add playButton to pauseLayer
}
//Spawn
func spawnEnemy(){
//Start spawning, moving and removing
let spawnEnemy = SKAction.runBlock({
() in
//Spawn enemy
self.setupEnemy()
self.gameLayer.addChild(self.enemy)
//Move left and remove when go off screen
let frameWidth = CGFloat(self.frame.width)
let moveEnemy = SKAction.moveByX(-frameWidth - 50, y: 0, duration: NSTimeInterval(0.0028 * frameWidth)) //duration: faster or slower
let removeEnemy = SKAction.removeFromParent()
var moveAndRemove = SKAction()
moveAndRemove = SKAction.sequence([moveEnemy, removeEnemy])
self.enemy.runAction(moveAndRemove)
})
//Spawn enemy each 2 seconds
let spawnEnemyDuration = SKAction.repeatActionForever(SKAction.sequence([spawnEnemy, SKAction.waitForDuration(2.0)]))
gameLayer.runAction(spawnEnemyDuration)
}
override func didMoveToView(view: SKView) {
/* Setup your scene here */
print ("didMoveToView")
registerAppTransitionObservers()
cageObjects()
checkPause = false
createGameLayer()
createPauseLayer()
self.addChild(gameLayer)
spawnEnemy()
}
//Game states
func pauseState(){
//Pause game
pauseButton.hidden = true //hide pauseButton
gameLayer.paused = true //pause gameLayer
checkPause = true //game is paused
self.addChild(pauseLayer) //add pauseLayer
}
func playState(){
pauseLayer.removeFromParent() //remove pauseLayer
//Resume game
checkPause = false //game is not paused
gameLayer.paused = false //unpause gameLayer
pauseButton.hidden = false //show pauseButton
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
/* Called when a touch begins */
//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()
}
}
}
//Functions from AppDelegate
func registerAppTransitionObservers(){
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(GameScene.applicationDidBecomeActive), name: UIApplicationDidBecomeActiveNotification, object: nil)
}
//Just launched
func applicationDidBecomeActive(){
print("DidBecomeActive")
//gameLayer unpausing problem solving attempt
if checkPause == true{
gameLayer.paused = true
}
//Pause when game is not paused and user leave the screen OR when game is launched
else if checkPause == false{
pauseState()
}
}
}
答案 0 :(得分:1)
现在我有你的来源,我看到了你的问题。
您需要保留暂停状态:
class GameScene : SKScene
{
...
override var paused: Bool
{
get{
return super.paused;
}
set{
let value = self.gameLayer.paused
super.paused = newValue;
self.gameLayer.paused = value;
}
}
}
出于某种原因,暂停的场景决定取消暂停其下的所有节点
此外,您应该在离开应用时暂停游戏,而不是在您回来时暂停游戏。
//Functions from AppDelegate
func registerAppTransitionObservers(){
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(GameScene.applicationWillResign), name: UIApplicationWillResignActiveNotification, object: nil)
}
func applicationWillResign(){
print("WillResignActive")
pauseState()
}
你可以摆脱那个检查暂停变量,即多余的膨胀代码。