Я сделал пример, где глобальная структура используется для отслеживания информации о previousScene
. Это также можно сделать с помощью пользовательского свойства или с помощью пользовательских данных, которые есть у каждого узла. Логика та же. Кроме того, я удалил код отладки (код метки отладки и т. д.), потому что не важно, чтобы все работало.
Пример мог бы быть лучше, если бы я добавил несколько кнопок, каждая из которых ссылается на определенную сцену, но я оставил только одну кнопку, чтобы все было максимально коротким.
Что вам нужно знать об этом примере (вы измените эти правила в соответствии с вашей игрой, но логика та же — установите предыдущую сцену перед фактическим переходом):
- есть три сцены: WelcomeScene (по умолчанию), MenuScene и GameScene.
- нажав на черную кнопку, вы попадете в GameScene. Существует исключение из этого правила, когда текущая сцена является GameScene. В этом случае переход приведет вас к предыдущей сцене.
- нажатие в любом месте вокруг черной кнопки приведет вас к предыдущей сцене. Существует исключение из этого правила, когда WelcomeScene загружается в первый раз (предыдущая сцена не установлена), и в этом случае переход приведет вас к MenuScene.
- в вашем GameViewController вы должны настроить WelcomeScene по умолчанию. В противном случае вам следует немного изменить код, чтобы обрабатывать ситуации, которые происходят, когда предыдущая сцена не установлена (как я сделал в touchesBegan из WelcomeScene).
Так что это правила, которые я создал, просто для того, чтобы сделать все эти переходы немного более значимыми...
Вот код (BaseScene.swift):
import SpriteKit
enum SceneType: Int {
case WelcomeScene = 0
case MenuScene //1
case GameScene //2
}
struct GlobalData
{
static var previousScene:SceneType?
//Other global data...
}
class BaseScene:SKScene {
let button = SKSpriteNode(color: SKColor.blackColor(), size: CGSize(width: 50, height: 50))
override func didMoveToView(view: SKView) {
setupButton()
}
private func setupButton(){
if (button.parent == nil){
//Just setup button properties like position, zPosition and name
button.name = "goToGameScene"
button.zPosition = 1
button.position = CGPoint(x: CGRectGetMidX(frame), y: 100)
addChild(button)
}
}
func goToScene(newScene: SceneType){
var sceneToLoad:SKScene?
switch newScene {
case SceneType.GameScene:
sceneToLoad = GameScene(fileNamed: "GameScene")
case SceneType.MenuScene:
sceneToLoad = MenuScene(fileNamed: "MenuScene")
case SceneType.WelcomeScene:
sceneToLoad = WelcomeScene(fileNamed:"WelcomeScene")
}
if let scene = sceneToLoad {
scene.size = size
scene.scaleMode = scaleMode
let transition = SKTransition.fadeWithDuration(3)
self.view?.presentScene(scene, transition: transition)
}
}
}
Каждая сцена (WelcomeScene, MenuScene, GameScene) наследуется от класса BaseScene (который является подклассом SKScene). Думаю, нет необходимости объяснять это, но не стесняйтесь спрашивать, если вас что-то смущает. Важным методом здесь (который используется каждым подклассом) является goToScene(scene:SceneType) и его параметр (типа SceneType), который сообщает нам, какой тип сцены должен загрузить метод.
SceneType — это просто перечисление, которое содержит целые числа... Так что на самом деле мы здесь не работаем с объектами, поэтому не нужно бояться циклы надежных ссылок.
Далее идут другие сцены (WelcomeScene.swift):
import SpriteKit
class WelcomeScene:BaseScene {
override func didMoveToView(view: SKView) {
super.didMoveToView(view)
self.backgroundColor = SKColor.darkGrayColor()
}
deinit {print ("WelcomeScene deinited")}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
let touch = touches.first
if let location = touch?.locationInNode(self){
//Give a priority to a button - if button is tapped go to GameScene
let node = nodeAtPoint(location)
if node.name == "goToGameScene"{
GlobalData.previousScene = SceneType.MenuScene
goToScene(SceneType.GameScene)
}else{
//Otherwise, do a transition to the previous scene
//Get the previous scene
if let previousScene = GlobalData.previousScene {
GlobalData.previousScene = SceneType.WelcomeScene
goToScene(previousScene)
}else{
// There is no previousScene set yet? Go to MenuScene then...
GlobalData.previousScene = SceneType.WelcomeScene
goToScene(SceneType.MenuScene)
}
}
}
}
}
Чтобы быть кратким, все прокомментировано. Следующий код (MenuScene.swift):
import SpriteKit
class MenuScene: BaseScene {
override func didMoveToView(view: SKView) {
super.didMoveToView(view)
backgroundColor = SKColor.purpleColor()
}
deinit {
print ("MenuScene deinited") //If this method isn't called, you might have problems with strong reference cycles.
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
let touch = touches.first
if let location = touch?.locationInNode(self){
//Give a priority to a button - if button is tapped go to GameScene
let node = nodeAtPoint(location)
if node.name == "goToGameScene"{
GlobalData.previousScene = SceneType.MenuScene
goToScene(SceneType.GameScene)
}else{
//Otherwise, do a transition to the previous scene
//Get the previous scene
if let previousScene = GlobalData.previousScene {
GlobalData.previousScene = SceneType.MenuScene
goToScene(previousScene)
}
}
}
}
}
И напоследок (GameScene.swift):
import SpriteKit
class GameScene: BaseScene{
override func didMoveToView(view: SKView) {
super.didMoveToView(view)
self.backgroundColor = SKColor.orangeColor()
}
deinit {print ("GameScene deinited")}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
//Here, we ignore black button because we don't want to transition to the same scene
if let previousScene = GlobalData.previousScene {
GlobalData.previousScene = SceneType.GameScene
goToScene(previousScene)
}
}
}
Предварительный просмотр:
а>
Просто прочитайте еще раз правила с самого начала, и все будет в порядке (например, в GameScene черная кнопка не работает, или при первом запуске не установлена предыдущая сцена, поэтому по умолчанию вы будете переведены в MenuScene).
Вот и все. Надеюсь, что это помогает немного. Вы можете скопировать и вставить код, чтобы протестировать его и улучшить в соответствии с вашими потребностями. Тем не менее, не уверен, что вам это действительно нужно. Похоже, вам просто нужно правильно переходить между сценами.
СОВЕТ. Здесь важно то, что каждая сцена BaseScene, WelcomeScene... имеет собственный файл .sks. Вы создаете их из File->New->File->Resource и называете их соответствующим образом (например, BaseClass.sks, WelcomeScene.sks...). Кроме того, ваша работа — поддерживать состояние переменной GlobalData.previousScene
(например, установить ее перед переход сделан).
person
Whirlwind
schedule
29.12.2015