Я разрабатываю игру SpriteKit, используя GKStateMachine для перехода между несколькими сценами.Я использую класс, который содержит экземпляр StateMachine, который имеет несколько состояний.Сами состояния имеют доступ к текущему SKView через свойство инициализатора.Штаты отвечают за представление сцен, поэтому у них есть свойство сцены, которое будет представлено в методе didEnter.Теперь у меня есть MainMenuState, в котором есть сцена с 3 кнопками.Для передачи событий кнопки в штат я написал пользовательский делегат.MainMenuState реализует протокол делегата и устанавливает для свойства делегата сцены значение «self».Поэтому, когда пользователь нажимает кнопку, действие перенаправляется в метод делегата.Я хотел использовать метод делегата для перехода в следующее состояние (например, SettingsState).Однако когда я пытаюсь получить доступ к свойству GKStates StateMachine в функции делегата, оно всегда равно нулю.Я думаю, что у меня есть проблема с дизайном, и я не знаю, как ее решить.
Код MainMenuState
import Foundation
import GameplayKit
class MainMenuState : GKState, MenuSceneDelegate {
var view: SKView
var scene: GKScene?
init(view: SKView) {
self.view = view;
self.scene = GKScene(fileNamed: "MenuScene")
super.init()
}
override func isValidNextState(_ stateClass: AnyClass) -> Bool {
return stateClass is MultiplayerHostState.Type ||
stateClass is MultiplayerSearchState.Type ||
stateClass is SettingsState.Type
}
override func didEnter(from previousState: GKState?) {
super.didEnter(from: previousState)
// Load 'GameScene.sks' as a GKScene. This provides gameplay related content
// including entities and graphs.
if let scene = self.scene {
// Get the SKScene from the loaded GKScene
if let sceneNode = scene.rootNode as! MenuScene? {
// Set delegate
sceneNode.menuDelegate = self
// Copy gameplay related content over to the scene
sceneNode.entities = scene.entities
sceneNode.graphs = scene.graphs
// Set the scale mode to scale to fit the window
sceneNode.scaleMode = .aspectFill
sceneNode.size = view.bounds.size
// Present the scene
if let view = self.view as SKView? {
view.presentScene(sceneNode)
view.ignoresSiblingOrder = true
view.showsFPS = true
view.showsNodeCount = true
}
}
}
}
override func willExit(to nextState: GKState) {
super.willExit(to: nextState)
}
func hostGameClicked() {
if let stateMachine = self.stateMachine {
stateMachine.enter(MultiplayerHostState.self)
}
}
func joinGameClicked() {
if let stateMachine = self.stateMachine {
stateMachine.enter(MultiplayerSearchState.self)
}
}
func settingsClicked() {
// <-- Here the StateMachine is nil -->
if let stateMachine = self.stateMachine {
stateMachine.enter(SettingsState.self)
}
}
}