【问题标题】:How to add an .sks files to existing Swift/Sprite-Kit project?如何将 .sks 文件添加到现有的 Swift/Sprite-Kit 项目?
【发布时间】:2017-02-09 23:41:28
【问题描述】:

我开始关注 Ray Wenderlich 的“太空入侵者”教程,但分歧很大。我现在有 3 个 SKScene - 我的标题屏幕、我的主游戏屏幕和我的最终关卡/游戏结束屏幕。我添加的标题屏幕和结束游戏场景,它们都有 .sks 文件;主游戏屏幕没有,所有元素(SKSpriteNodes 等)都以编程方式放置。我的程序流程如下:

我现在实际上想通过场景编辑器放置主游戏屏幕的一些事件,因此我为其创建了一个 .sks 文件并尝试将我的 titleScene.swift 更改如下:

来自:

    let gameScene = GameScene(size:CGSize(width: 1536, height: 2048))

到:

    let gameScene = SKScene(fileNamed: "GameScene.sks") as! GameScene!

但是,这会给出:

我试图删除 required init(coder aDecoder: NSCoder) 但 Xcode 然后抱怨说

required init(coder: 必须由 SKScene 的子类提供

但是我的 titleScenegameOverScene 也是 SKScene 的子类,它们没有 init(coder:)

我真的看不出我通过 (fileNames:) 和他们的 .sks 文件显示我的 titleScreen 和我的 gameOverScene 并尝试为我的 gameScene 做同样的事情的区别。

【问题讨论】:

  • 试试这样: if let gameScene = GameScene(fileNamed: "GameScene"){ }
  • 现在我得到:“调用中的参数不正确(有'文件名:',预期的'大小:')。我很确定我缺少一些简单的东西......
  • 从 .sks 加载场景时不使用 InitWithSize。我不明白为什么你的 GameScene 中有它?去掉它,用coder去掉init的实现就可以了。
  • @Whirlwind - 好的。我删除了 init(size: 和 init(code: 现在我从 Xcode 收到一个错误,指出“Class GameScene has no initialisers”
  • 大声笑我还没有意识到您的问题与我之前已经评论过几次的问题相似,例如在this question 中,我假设您正在处理没有任何自定义属性的场景子类: ) 如果是这种情况,将自动调用默认初始化程序,并且不需要任何其他初始化程序实现。不管怎样,@Knight0fDragon 给出了关于初始化过程的很好的答案,就像他说的,你会在一段时间后习惯它:)

标签: ios swift sprite-kit init


【解决方案1】:

获得所需的原因是因为您的变量不是可选的或在 init 发生之前未初始化。

如果您有需要在 init 函数内部分配的变量,那么您会这样做:

required init?(coder aDecoder: NSCoder)
{
   super.init(coder: aDecoder)
}

然后你会问我:Knight0fDragon 先生,它告诉我将fileNamed 替换为coder,我切换时它没有编译。

这是因为init(fileNamed:) 是一个方便的init,而不是指定的init。为了能够对一个类进行子类化并获得它的所有便利 inits,您需要覆盖它的所有指定 inits。

现在有了 SKScene,您有 3 个,而您已经知道 1 个。

让我们覆盖另外两个:

override init() {
    super.init()
}
override init(size: CGSize) {
    super.init(size: size)
}

好的,现在这只小狗应该可以编译了,我们只需要分配变量。

我喜欢做的是为在调用 super 之后必须在任何版本的初始化中分配的任何变量创建一个设置方法。

不幸的是,我们不能在调用 super 之前对常量执行此操作,因此我们需要在每个方法中设置这些常量。原因是self 还不完全存在。

这最终会是这样的:

let constant : String
required init?(coder aDecoder: NSCoder)
{
   constant = "hi"
   super.init(coder: aDecoder)
   setup()
} 
override init() {
    constant = "hi"
    super.init()
    setup()
}
override init(size: CGSize) {
    constant = "hi"
    super.init(size: size)
    setup()
}

【讨论】:

  • 非常好 - 修复了它。非常感谢。所以我的 gameScene 和 TitleScene/gameOverScene 之间的区别是只有 gameScene 有未初始化的存储属性。我知道 Swift 中的初始化听起来有点棘手(你可能不会理解),但以前从未遇到过。
  • 嗯嗯,你会习惯的
  • 这是一个很好的例子,说明你开始向读者传授大量的洞察力和理解力(从而赋予读者权力),说明初始化如何以及为什么在 Swift 中如此重要!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多