Search code examples
iosiphoneswiftsprite-kitresolution

How to exactly measure size & position of Swift nodes depending on iDevice


I'm creating my first Swift + SpriteKit game, and I'm dealing with this headache of having to resize all my stuff depending on the iDevice.

I got a class that based on the device its running, returns the name of it. Having that name, I created a dictionary that based on a device String name, returns the resolution of that given device.

And then I created 2 functions -> getSizeBasedOnDevice() and getPositionBasedOnDevice()

Since I coded my game for an iPhone 6S. I thought that it would be as easy as doing a simple math calculation to get all these sizes and positions, but it looks like it wasn't.

These are my functions:

func getSizeBasedOnDevice(width: CGFloat, height: CGFloat) -> CGSize {
    // iPhone 6s w: 375, h: 667

    let deviceName = UIDevice.currentDevice().modelName
    let iphoneNative = ScreenSize(width: 375, height: 667)
    let resolution = Resolutions[deviceName]

    let newWidth = (CGFloat(resolution!.getWidth()) * width ) / iphoneNative.getWidth()
    let newHeight = (CGFloat(resolution!.getHeight()) * height) / iphoneNative.getHeight()

    return CGSize(width: newWidth, height: newHeight)
}

func getPositionBasedOnDevice(x: CGFloat, y: CGFloat) -> CGPoint {

    let deviceName = UIDevice.currentDevice().modelName
    let iphoneNative = ScreenSize(width: 375, height: 667)
    let resolution = Resolutions[deviceName]

    let newX = (CGFloat(resolution!.getWidth()) * x) / iphoneNative.getWidth()
    let newY = (CGFloat(resolution!.getHeight()) * y) / iphoneNative.getHeight()

    return CGPoint(x: newX, y: newY)
}

My iPhoneNative height and width would be my iPhone 6S'. So the calculation was kinda simple to me, but it wasn't.

So having these example values:

Asset's width = 100 pts
Current Device (iPhone 4S) width = 320 pts
Originally designed Device (iPhone 6S) width = 375 pts

The math would be:

(320 * 100) / 375 = 85.33

So the asset that had a 100 points width on my iPhone 6S would have 85.33 width on an iPhone 4S.

First I thought this seemed to be fine, but looking at the results, I see I was doing it wrong.

Can anyone give me a hint?

Thanks in advance.


Solution

  • Let me stop you :)

    I understand your difficulties, this is not the right way to build a game for different screen sizes.

    You should build your game only thinking about the Scene.

    Then open GameViewController.swift and look for this line

    scene.scaleMode = .AspectFill
    

    This line does allow you to define how a scene should be represented into a screen (and it's particularly important for dealing with different screen sizes).

    You have 4 options

    • .Fill: Scale the SKScene to fill the entire SKView.
    • .AspectFill: Scale the SKScene to fill the SKView while preserving the scene's aspect ratio. Some cropping may occur if the view has a different aspect ratio.
    • .AspectFit: Scale the SKScene to fit within the SKView while preserving the scene's aspect ratio. Some letterboxing may occur if the view has a different aspect ratio.
    • .ResizeFill: Modify the SKScene's actual size to exactly match the SKView.