Фатальная ошибка: использование нереализованного инициализатора "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")
}
}