Фатальная ошибка: использование нереализованного инициализатора "init (размер:)" для класса

Я тестировал свое приложение на разных устройствах и понимал, что движения спрайтов были совершенно непоследовательными (на некоторых устройствах они выполнялись значительно быстрее, чем другие). Я нашел этот пост и выполнил инструкции и удалил параметры размера из всех моих SKScene, после чего получил ошибку:

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

См. ниже мой класс PosterScene и класс GameViewController, в котором он вызывается.

PosterScene

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")
}
}

GameViewController:

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)!
}
}

Ответ 1

Вы попросили меня взглянуть на этот вопрос.

Вы не чувствуете себя единообразно на разных устройствах, потому что в вашем GameViewController вы устанавливаете режим масштаба сцены на .resizeFill. В большинстве случаев настройка по умолчанию .aspectFill является наилучшим вариантом.

В отношении сообщения об ошибке вам нужно указать размер сцены в методе init, если вы не используете редактор уровня xCode, например

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

В основном есть 2 варианта размера

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 и меньше на iPads, например. Лумино. Таким образом, размер сцены будет тем, что использует xCode 8, либо 1334x750 (пейзаж), либо 750x1334 (портрет).

Таким образом, ваша игра должна быть последовательной на всех устройствах. Единственное, что вам нужно сделать, это настроить некоторые пользовательские интерфейсы, такие как расположение кнопок, между iPad и iPhone.

Надеюсь, что это поможет

Ответ 2

Вот как выглядит ваш макет кода. Как вы можете видеть, я создал сцену размером с iPhone 6. Это означает, что на всех других телефонах изображение будет масштабироваться (но вы все равно увидите все), но будет выглядеть идеально на 6. На iPad, изображение будет нарезано сверху и снизу на 12,5% каждый, из-за того, что iPad составляет 3: 4, а не 9:16

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 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")
}
}