Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SpriteKit Scene doesn't fit entire view on the iPhone X

The iPhone X is released a few days ago. I am trying to update one of my game to the new phone. However, on one scene with SpriteKit scene, the scene doesn't scale to fill the entire screen.

Here is the code to display the scene:

GameScene *scene = [GameScene unarchiveFromFile:@"GameScene"];
scene.scaleMode = SKSceneScaleModeFill;
// skView is basically self.view casted to SKView
[skView presentScene:scene];

The size of the scene in the SKS file is 2048x1536.

This is what it looks like:

Picture

The red part is the scene content. One interesting thing is, the background (which is the blue and gray, does get displayed properly.

Anyway to fix this? I'm fine with just stretching the scene to fill the display (there won't be anything covered up by the rounded corner and the notch)

like image 534
Tom Shen Avatar asked Sep 15 '17 11:09

Tom Shen


1 Answers

There might be a cleaner approach for SpriteKit games to support iPhone X screen, but I came out with the following extension for SKView:

public extension SKView {
    func isIphoneX() -> Bool {
        let screenHeight = 2436.0
        let screenWidth = 1125.0
        let iphoneXAspectRatio = screenHeight / screenWidth

        let aspectRatio = Double(self.frame.width/self.frame.height)
        return (aspectRatio == iphoneXAspectRatio) ? true : false
    }
}

And the usage: Basically it sets the scale mode according to the screen's aspect ratio. If it's an iPhone X aspect ratio set the scale mode to "resizeFill", otherwise for the classic rectangle iPhone and iPad screens use the "aspectFill" mode.

import SpriteKit

class GameViewController: UIViewController {

    // MARK: - View lifecycle
    override func viewDidLoad() {
        super.viewDidLoad()

        guard let view = self.view as? SKView else { return }
        guard let scene = SKScene(fileNamed: "sceneName") else { return }
        scene.scaleMode = view.isIphoneX() ? .resizeFill : .aspectFill

        view.presentScene(scene)
    }
}

I found that resizeFill mode is the only way to make the content fill the whole iPhone X screen without distorting or clipping off the scene's content. If you have a HUD node in the game (score, counters, buttons, etc...) you need to make changes to that as well!

override func didMove(to view: SKView) {
   // Any additional setup... 
   ...

    if view.isIPhoneX {
        hud = SKReferenceNode(fileNamed: "yourIPhoneXHUDScene")
    } else {
        hud = SKReferenceNode(fileNamed: "yourStandardHUDScene")
    }

    cam.addChild(hud)
}

Tested with every iPhone screen size (3.5", 4", 4.7", 5.5", 5.8") in the simulator. However I'm not sure how to deal with gamescenes with retina iPad size (2048 x 1536) set in Xcode.

like image 114
balazs630 Avatar answered Nov 08 '22 07:11

balazs630