【问题标题】:fatal error: use of unimplemented initializer 'init(size:)' for class致命错误:对类使用未实现的初始化程序“init(size:)”
【发布时间】:2017-03-22 13:11:15
【问题描述】:

我在不同设备上测试我的应用,发现精灵的动作非常不一致(与其他设备相比,在某些设备上运行速度要快得多)。我找到了this post 并按照说明从我所有的SKScenes 中删除了大小参数,然后我得到了错误:

fatal error: use of unimplemented initializer 'init(size:)' for class 'SuperGame.PosterScene'

请查看下面我的PosterScene 类和调用它的GameViewController 类。

海报场景

class PosterScene: SKScene {

 override init(){
    super.init()

    let posterImage = SKSpriteNode(imageNamed: "poster")
    posterImage.position = CGPoint(x: self.frame.midX, y: self.frame.midY)
    self.addChild(posterImage)

    let sequence = SKAction.sequence([  SKAction.wait(forDuration: 3.0), SKAction.run({ self.changeToMainMenuScene() }) ])

    self.run(sequence)

}

func changeToMainMenuScene  ()  {

    let mainMenuScene = MainMenuScene()
    self.view!.presentScene(mainMenuScene)

}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}
}

游戏视图控制器:

class GameViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()

}

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()

    let skView = self.view as? SKView

    if skView?.scene == nil  {
        skView?.showsFPS = true
        skView?.showsNodeCount = true
        skView?.showsPhysics = true
        skView?.ignoresSiblingOrder = false

        //starting the game with the Poster Scene
        let posterScene = PosterScene()
        posterScene.scaleMode = .resizeFill
        skView?.presentScene(posterScene)
    }

}

override var shouldAutorotate : Bool {
    return true
}

override var supportedInterfaceOrientations : UIInterfaceOrientationMask {
    if UIDevice.current.userInterfaceIdiom == .phone {
        return UIInterfaceOrientationMask.allButUpsideDown
    } else {
        return UIInterfaceOrientationMask.all
    }
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Release any cached data, images, etc that aren't in use.
}

override var prefersStatusBarHidden : Bool {
    return true
}

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

【问题讨论】:

  • 你应该覆盖init(size:),而不是init()
  • @dan 我最初使用的是init(size:),它没有给出任何错误,但精灵速度在不同设备上有所不同。为了解决精灵速度变化的问题,我按照链接问题中的建议删除了 size 参数。
  • @iGetIt,现在我可以在代码中看到这一点,你误会我了,我没有说不要使用size: 我说不要使用size:view.frame.size。如果您必须 100% 在代码中工作(我不建议这样做,分离设计和功能会使生活轻松 1000 倍)那么您应该选择静态大小,而不是基于视图的大小,因为目标是在所有设备,使其看起来相同。

标签: ios swift sprite-kit swift3


【解决方案1】:

你让我看看这个问题。

您的游戏在不同设备上的感觉不一致,因为在 GameViewController 中您将场景缩放模式设置为 .resizeFill。 在大多数情况下,默认的 .aspectFill 设置是最佳选择。

关于错误消息,当您不使用 xCode 级别编辑器时,您需要在 init 方法中为场景指定大小,例如

let scene = GameScene(size: CGSize(width: ..., height: ...))

尺寸基本上有两种选择

1) 将场景大小设置为 iPad,这是我个人做的。这也是 Apple 在 DemoBots 中使用的内容以及 xCode 7 中的默认设置。因此场景大小为 1024x768(横向)或 768x1024(纵向)。

我在设计游戏区域时考虑了 iPhone,并在 iPad 上简单地展示了更多背景,通常是地面和天空。这就是我喜欢玩的许多流行游戏所做的事情,例如Modern Combat 5、Limbo、Altos Adventure、Leos Fortune、The Line Zen、Tower Dash。

2) 将场景大小设置为 iPhone,并在 iPhone 上显示更多背景,在 iPad 上显示更少背景,例如卢米诺城。 所以场景大小将是 xCode 8 使用的,1334x750(横向)或 750x1334(纵向)。

这样,您的游戏应该在所有设备上都感觉一致。您唯一需要做的就是在 iPad 和 iPhone 之间调整一些 UI,例如按钮位置。

希望对你有帮助

【讨论】:

  • 来自印刷和运动的线性娱乐媒体,我倾向于建议这种从理想理想中裁剪的技术是最好的方法。它既有利于体验的一致性,也有利于(更重要的是)创意体验。
  • 是的,绝对同意。在我改变方法之前,我花了 8 个月的时间和 2 场比赛以手动方式进行,没有任何裁剪 (.resizeFill)。让它在所有设备上获得一致的体验真是太疯狂了。就像你说的那样,它还扼杀了我的创作体验,因为我有一半时间在为我没有测试的设备调整东西,而不是改进实际游戏本身。
  • 是的!在一个完全被“跨平台”炒作所迷惑的世界里,我们几乎忘记了我们获得出色体验的原因(首先)是因为有创造力的人的创造性努力。人们受到启发,然后坚持通过将想法和概念制作成虚拟现实的生产问题和实现挫折。实现和生产的所有障碍都会损害创造力。我非常感谢你在这里和在 git 上为此做出的非常有帮助的贡献,让我(和其他人)的 SpriteKit 生活更轻松。
  • 非常正确。谢谢你的好话,就像帮助别人一样。当我开始使用 SpriteKit 和 Swift 时,我也处于同样的境地,并且总是感谢人们花时间回答我当时简单且可能很愚蠢的问题。
  • @crashoverride777 你说你从中心设计你的游戏区域。这是否意味着你的 (0,0) 是中心?
【解决方案2】:

这是您的代码布局的外观。如您所见,我将场景设计为 iPhone 6 的大小。这意味着在所有其他手机上,图像会缩放(但您仍然会看到所有内容),但在 6 上看起来很完美。在 iPad 上,由于 iPad 是 3:4 而不是 9:16,图像将在顶部和底部各切掉 12.5%

class GameViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()

}

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()

    let skView = self.view as? SKView

    if skView?.scene == nil  {
        skView?.showsFPS = true
        skView?.showsNodeCount = true
        skView?.showsPhysics = true
        skView?.ignoresSiblingOrder = false

        //starting the game with the Poster Scene
        let posterScene = PosterScene(size:CGSize(width:375,height:667))
        posterScene.scaleMode = .aspectFill
        skView?.presentScene(posterScene)
    }

}

override var shouldAutorotate : Bool {
    return true
}

override var supportedInterfaceOrientations : UIInterfaceOrientationMask {
    if UIDevice.current.userInterfaceIdiom == .phone {
        return UIInterfaceOrientationMask.allButUpsideDown
    } else {
        return UIInterfaceOrientationMask.all
    }
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Release any cached data, images, etc that aren't in use.
}

override var prefersStatusBarHidden : Bool {
    return true
}

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

class PosterScene: SKScene {

 override init(size:CGSize){
    super.init(size:size)
    self.anchorPoint = CGPoint(x:0.5,y:0.5) //let's put 0,0 at the center of the screen
    let posterImage = SKSpriteNode(imageNamed: "poster")
    posterImage.position = CGPoint.zero
    self.addChild(posterImage)

    let sequence = SKAction.sequence([  SKAction.wait(forDuration: 3.0), SKAction.run({ self.changeToMainMenuScene() }) ])

    self.run(sequence)

}

func changeToMainMenuScene  ()  {

    let mainMenuScene = MainMenuScene()
    self.view!.presentScene(mainMenuScene)

}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}
}

【讨论】:

  • 我想我将不得不对我所有的SKScenes 使用相同的方法。我的 iPad 图像有 25% 被裁剪,这有点问题。有没有办法解决这个问题?
  • 好吧,你想做什么,iphone和ipad不可能完全一样,所以我需要知道你打算做什么
  • @Knight0fDragon 我也一直在与这个问题作斗争。我的SKScenes 经常使用self.size。我是否也必须用 UIScreen.main.bounds.size 替换它们?
  • @Knight0fDragon 我刚刚阅读了这篇文章以及链接的文章和所有的 cmets。就个人而言,我更喜欢使用 iGetIt 处理位置和尺寸的原始方式,并且从外观上看,他将不得不做出改变的世界来实施您的建议。我相信应该有一种更简单的方法让他获得一致的精灵运动。通过根据屏幕尺寸或类似的东西找到一个乘以精灵速度的因素。这是我的看法。
  • @chronos,另外,您现在必须担心不同设备的纵横比,当精灵沿对角线移动时,它在不同设备上的外观如何。它在 ipad 上可能看起来很棒,但在 iphone 上看起来很糟糕,因为您的精灵更多地向上移动,然后向右移动。有很多事情要考虑,这很疯狂,这就是游戏开发的魅力所在,有很多问题需要解决。
猜你喜欢
  • 1970-01-01
  • 2014-07-25
  • 2019-04-23
  • 1970-01-01
  • 2018-09-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多