swift - 从另一个 bundle 加载一个 spritekit 场景?

标签 swift macos sprite-kit

我正在使用 swift 4.2 制作 SpriteKit 框架,并希望包含一些用于场景和 Action 的 .sks 文件。我尝试使用以下代码从包中加载场景:

class func newGameScene() -> GameScene {

guard let gameScenePath = Bundle(for: self).path(forResource: "GameScene", ofType: "sks") else { assert(false) }

guard let gameSceneData = FileManager.default.contents(atPath: gameScenePath) else { assert(false) }

let gameSceneCoder = NSKeyedUnarchiver(forReadingWith: gameSceneData)

guard let scene = GameScene(coder: gameSceneCoder) else { assert(false) }


// Set the scale mode to scale to fit the window
scene.scaleMode = .aspectFill

return scene

我加载场景并呈现它。 (此代码主要来自 Apple 的 SpriteKit 模板,因为我正在测试此问题。)

guard let view = view else {
      return nil
    }

    let scene = GameScene.newGameScene()

    view.presentScene(scene)

    view.ignoresSiblingOrder = true
    view.showsFPS = true
    view.showsNodeCount = true
    return nil

在这种情况下,GameScene.sks 和代码与 Apple 模板没有变化。此代码和 .sks Assets 位于动态框架中并导入到另一个项目中。

当让框架将场景加载到我传递的 View 中时,它显示 fps 和节点数但不显示“Hello, World!”文本。

在下面的代码中,也是从模板中复制的,一个断点表明这些在鼠标按下时不会被调用。

    #if os(OSX)
// Mouse-based event handling
extension GameScene {

  override func mouseDown(with event: NSEvent) {
    if let label = self.label {
      label.run(SKAction.init(named: "Pulse")!, withKey: "fadeInOut")
    }
    self.makeSpinny(at: event.location(in: self), color: SKColor.green)
  }

  override func mouseDragged(with event: NSEvent) {
    self.makeSpinny(at: event.location(in: self), color: SKColor.blue)
  }

  override func mouseUp(with event: NSEvent) {
    self.makeSpinny(at: event.location(in: self), color: SKColor.red)
  }

}
#endif

我知道这一定与 SpritKit 加载场景的方式有关,但找不到解决方案。我必须使用 NSKeyedUnarchiver 因为 SpritKit 的内置文件初始化器:

GameScene(fileNamed: "GameScene")

仅从 Main Bundle 加载。

现在在上面我假设可以使用编码器加载文件,但 Tomato 指出 sks 很可能不是使用编码器保存的。在这种情况下,可能无法使用 apple 提供的 api 从 sprite-kit 中的另一个包加载 sks 文件。答案可能不包括编码员。

最佳答案

我已将上述讨论/解决方案编译成 SKScene 上的单个扩展函数。希望这对某人有帮助!

import SpriteKit

extension SKScene {
    static func fromBundle(fileName: String, bundle: Bundle?) -> SKScene? {
        guard let bundle = bundle else { return nil }
        guard let path = bundle.path(forResource: fileName, ofType: "sks") else { return nil }
        if let data = FileManager.default.contents(atPath: path) {
            return NSKeyedUnarchiver.unarchiveObject(with: data) as? SKScene
        }
        return nil
    }
}

关于swift - 从另一个 bundle 加载一个 spritekit 场景?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50729195/

相关文章:

swift - Swift 中没有类/结构自动完成

64 位 Mac OSX 上的 mysql 工作台

xcode - 从Sprite套件中的类调用方法?

ios - for 循环错误

ios - 修复 Swift simd 库中的错误(以及缺少文档?)

ios - 旋转后的 CollectionView 布局

swift - 无法将 segmentedControl 设置回未选择索引

ios - 如何通过 segue - Swift 从结构对象数组发送变量

Android 命令已被弃用

ios - 如何在 OS EL Capitan 10.11.1 中运行 Xcode 5.1.1?