虽然有些游戏选择放弃暂停菜单 - 假设因为游戏时间较短,例如Don't Grind - 我个人认为暂停游戏是一项关键功能,并希望了解如何实施它在Swift 3中为SpriteKit。
我已经看到尝试使用UIAlertController
来做到这一点,但是我 - 或许是错误的 - 相信更好的替代方案是在当前{{1}上覆盖SKView
}}。
我看过Apple的DemoBots,看看我是否能弄清楚他们是如何暂停比赛的。但是,在我的设备上下载并运行它后,它会导致错误,所以我不想跟风。但是,如果有人能够彻底解释过多的文件,例如" LevelScene + Pause"," SceneManager"," SceneOperation"等等以及它们如何协同工作,也会很酷。
如何在SKView
上叠加SKView
来制作暂停菜单?
M.W.E., StackOverflow SpriteKit with Menu,是一个准系统"游戏"将答案语境化。请回答有关M.W.E的问题。
以下是M.W.E的修改版本。该文件" GameScene"。 它考虑为要暂停的元素添加主节点,为暂停菜单添加另一个节点。
暂停菜单工作时,即使GameScene
,背景仍然有效。 (尝试点击最左边的蓝色精灵)。
//
gameNode.isPaused = true
答案 0 :(得分:2)
我在游戏场景中暂停游戏的问题已经挣扎了一段时间。
正如其他几个人在评论中所建议的那样,建立一个“暂停场景”,以便在游戏暂停时转换为一个有效的解决方案。这种方法可以避免在游戏暂停时或游戏停止时定时器在游戏场景中触发时可能遇到的问题。
为了实现暂停场景,我使用UIViewController
的自定义子类来处理场景转换。
在我的CustomViewController
:
var sceneForGame: MyGameScene? //scene to handle gameplay
var paused: PauseScene? //scene to appear when paused
...
// presentPauseScene() and unpauseGame() handle the transition from game to pause and back
func presentPauseScene() {
//transition the outgoing scene
let transitionFadeLength = 0.30
let transitionFadeColor = UIColor.white
let pauseTransition = SKTransition.fade(with: transitionFadeColor, duration: transitionFadeLength)
pauseTransition.pausesOutgoingScene = true
let currentSKView = view as! SKView
currentSKView.presentScene(paused!, transition: pauseTransition)
}
func unpauseGame() {
let transitionFadeLength = 0.30
let transitionFadeColor = UIColor.white
let unpauseTransition = SKTransition.fade(with: transitionFadeColor, duration: transitionFadeLength)
unpauseTransition.pausesIncomingScene = false
let currentSKView = view as! SKView
currentSKView.presentScene(sceneForGame!, transition: unpauseTransition)
}
在MyGameScene
类(SKScene
的子类)中:
var parentViewController: CustomViewController? // ref to the managing view controller
...
// invoke this func when you want to pause
func setScenePause() {
parentViewController?.presentPauseScene()
self.isPaused = true
}
...
// you may need a snippet like this in your game scene's didMove(toView: ) to wake up when you come back to the game
else if self.isPaused {
self.isPaused = false
}
这是我的PauseScene
实施。当用户点击暂停场景中的任何位置时,此版本将取消暂停,但endGameButton
除外,该终止当前游戏:
struct PauseNames {
static let endGameButton = "ENDGAME"
static let pausedButton = "PAUSE"
}
class PauseScene: SKScene {
var center : CGPoint?
var pauseButton: SKSpriteNode?
var endGameButton: SKSpriteNode?
var parentViewController: CustomViewController?
override func didMove(to view: SKView) {
setUpScene()
}
func setUpScene() {
self.backgroundColor = SKColor.white
self.center = CGPoint(x: self.size.width / 2, y: self.size.height / 2)
self.isUserInteractionEnabled = false
setUpSceneNodes()
showPauseEndButtons()
} // end setup scene
func setUpSceneNodes() {
let buttonScale: CGFloat = 0.5
let smallButtonScale: CGFloat = 0.25
let pauseOffset = //some CGPoint
let endGameOffset = //some CGPoint
pauseButton = SKSpriteNode(imageNamed: PauseNames.pausedButton)
pauseButton?.name = PauseNames.pausedButton
pauseButton?.anchorPoint = CGPoint(x: 0.5, y: 0.5)
pauseButton?.position = self.center! + pauseOffset
pauseButton?.alpha = 0
pauseButton?.setScale(buttonScale)
endGameButton = SKSpriteNode(imageNamed: PauseNames.endGameButton)
endGameButton?.name = PauseNames.pausedButton
endGameButton?.anchorPoint = CGPoint(x: 0.5, y: 0.5)
endGameButton?.position = self.center! + endGameOffset
endGameButton?.alpha = 0
endGameButton?.setScale(smallButtonScale)
}
func showPauseEndButtons() {
let buttonFadeInTime = 0.25
let pauseDelay = 1.0
self.addChild(pauseButton!)
self.addChild(endGameButton!)
pauseButton?.run(SKAction.fadeIn(withDuration: buttonFadeInTime))
endGameButton?.run(SKAction.fadeIn(withDuration: buttonFadeInTime))
self.run(SKAction.sequence([
SKAction.wait(forDuration: pauseDelay),
SKAction.run{ self.isUserInteractionEnabled = true }]))
}
func endGamePressed() {
// add confrim logic
parentViewController?.endGame()
}
func unpausePress() {
parentViewController?.unpauseGame()
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches {
let touchLocation = touch.location(in: self)
if endGameButton!.contains(touchLocation) {
endGamePressed()
return
}
else {
unpausePress()
}
} // end for each touch
} // end touchesBegan
override func update(_ currentTime: TimeInterval) {
/* Called before each frame is rendered */
}
} //end class PauseScene
(pauseButton
实际上更像是一个横幅,用于通知用户此版本中的暂停状态)