Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I was testing my app on different devices and realized the sprite movements were quite inconsistent (running considerably faster on some devices as compared to others). I found this post and followed the instructions and removed the size parameters from all my SKScenes then I got the error:

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

Please see my PosterScene class below and the GameViewController class in which it is called.

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)!
}
}
like image 473
iGetIt Avatar asked Nov 08 '16 19:11

iGetIt


2 Answers

You have asked me to take a look at this question.

You game does not feel consistent across devices because in your GameViewController you set scene scale mode to .resizeFill. In most cases the default .aspectFill setting is the best option.

In regards to the error message you need to give the scene a size in the init method when you are not using the xCode level editor e.g

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

There is basically 2 options for size

1) Set the scene size to iPad, which is what I personally do. This is also what Apple uses in DemoBots and what was the default setting in xCode 7. So scene size is either 1024x768 (landscape) or 768x1024 (portrait).

I design my game area with the iPhone in mind, and simply show some more background, usually ground and sky, on iPads. This is what a lot of popular games I like to play do e.g. Modern Combat 5, Limbo, Altos Adventure, Leos Fortune, The Line Zen, Tower Dash.

2) Set the scene size to iPhones and show more background on iPhones and less on iPads e.g. Lumino City. So scene size would be what xCode 8 uses, either 1334x750 (landscape) or 750x1334 (portrait).

This way your game should feel consistent across all devices. The only thing you might have to do is tweak some UI, like button positioning, between iPad and iPhone.

Hope this helps

like image 59
crashoverride777 Avatar answered Oct 21 '22 18:10

crashoverride777


Here is how your code layout should look. As you can see, I designed the scene to be the size of iPhone 6. This means on all other phones, the image will scale (but you will still see everything), but will look perfect on the 6. On the iPad, the image will get chopped off on the top and the bottom by 12.5% each, due to the iPad being a 3:4 and not 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)!
}
}

and

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")
}
}
like image 1
Knight0fDragon Avatar answered Oct 21 '22 17:10

Knight0fDragon