【问题标题】:How do you use the Delegate Protocol Pattern with SpriteKit?您如何将委托协议模式与 SpriteKit 一起使用?
【发布时间】:2020-05-03 06:41:23
【问题描述】:

所以我有一个UIViewController 和两个SKScenes。 UIViewController通过旋转设备呈现两个场景; landscape load SKScene 1 和 portrait load SKScene 2 说谎:

    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        print("TRIGGERED")

        if UIDevice.current.orientation.isLandscape {
            print("Landscape")
            presentView(name: "GameScene")
        } else {
            print("Portrait")
            presentView(name: "GameScene2")
        }
        super.viewWillTransition(to: size, with: coordinator)

    }

    func presentView(name: String) {
        if let view = self.view as! SKView? {
              if let scene = SKScene(fileNamed: name) {
                  scene.scaleMode = .aspectFill
                  view.presentScene(scene)
              }
              view.ignoresSiblingOrder = true
              view.showsFPS = true
              view.showsNodeCount = true
          }
    }

这很好用。然而,我的困境是我想在两个 SKScene GameSceneGameScene2 之间实现一个委托协议模式。问题是SKScene 1 的UIViewController (self) 应该作为代理传递给SKScene 2。因此,例如,如果用户在landscape 模式(GameScene)中单击某些东西,则某些数据@987654335当方向更改为portrait 时,@ 被传递给 GameScene2。

所以在SkScene 1:

protocol MyProtocol {
    func myProtocolFunc(someString: String)
}

class GameScene: SKScene{

    var myDelegate: MyProtocol!

UIViewController 中如何设置委托? scene.myDelegate 不起作用。 GameScene().myDelegate = GameScene2().self 有效,但因为 view.presentScene(scene) 用于呈现不相关的场景。如何访问和设置delegate?如何设置delegate-protocol 模式以获得所需的结果?

【问题讨论】:

    标签: swift sprite-kit delegates protocols


    【解决方案1】:

    使用 Swift 5

    protocol MyProtocol: AnyObject {
        func myProtocolFunc(someString: String)
    }
    
    class GameScene: SKScene {
        weak var myDelegate: MyProtocol?
    
        init(fileNamed: String) {
            super.init(fileNamed: fileNamed)
        }
    }
    

    然后,您必须在 presentView 方法中将场景对象创建为 GameScene,而不是 SKScene(就像您所做的那样)。所以而不是:

    if let scene = SKScene(fileNamed: name) // wrong
    

    你必须:

    if let scene = GameScene(fileNamed: name) // correct
    

    然后您可以轻松地使用scene.myDelegate 设置委托

    【讨论】:

    • 啊,谢谢!但是不使用SKScene(fileNamed: name) 是不是有一个权衡?我的意思是为什么默认情况下不这样做?
    • 您的GameScene(您也可以将其命名为MyPersonalGameScene)是SKScene 的子类。因此,您拥有 SKScene 提供的所有功能以及来自 GameScene 的自定义内容。
    • 好的,有道理。感谢您清除它!
    • 我能问一下你为什么使用:AnyObjectinit(fileNamed String)...吗?
    • GameScene 是您的代码。 “GameScene”是您的布局文件。如果这是一款棋盘游戏,请将 GameScene 视为规则,将“GameScene”视为棋子。如果这是大富翁,您可以拥有普通版和超级马里奥版。两者都可以使用相同的规则,但外观完全不同。
    猜你喜欢
    • 1970-01-01
    • 2017-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多