Luiz - 5 months ago 23x
Swift Question

# Universal game position

## Explanation

I'm building a game in a iPhone 5s, but now I want to make it universal, so it can run in all iPhones (or at least 4s ahead) and all iPads (or at least iPad 2 ahead).

By now, I pretty much created those 3 images (1x, 2x and 3x). So there's a 50x50 square (@1x), a 100x100 square (@2x) and a 150x150 square (@3x).

``````import SpriteKit

class GameScene: SKScene {

override func didMoveToView(view: SKView) {
/* Setup your scene here */

scene!.scaleMode = SKSceneScaleMode.ResizeFill //usually at GameViewController, not GameScene

let square = SKSpriteNode(imageNamed: "square")
square.anchorPoint = CGPointZero
square.position = CGPoint(x: self.frame.width / 1.095, y: self.frame.height / 1.1875) //superior right on iPhone 5/5s
}
}
``````

and these are the images:

## Testing

When I run on each device, this is happens:

• iPhone 4s - wrong position

• iPhone 5/5s - right position (it was set up here)

• iPhone 6/6s - wrong position

• iPhone 6+/6s+ - wrong position

• iPad 2 - wrong position

• iPad Pro - wrong position

• iPad Retina - wrong position

You can see better what happens by clicking on the image below.

## Question

Basically, my question is: how can I make this universal? I mean, how can I make the square be positioned at the same relative place on the devices above?

## Attempts

``````import SpriteKit

// MARK: Screen Dimensions
let screenWidth = CGFloat(1024)
let screenHeight = CGFloat(768)

// MARK: Node Sizes
let square = SKSpriteNode(imageNamed: "square")
let nodeConstantWidth = screenWidth/square.size.width * 0.088
let nodeConstantHeight = screenHeight/square.size.height * 0.158

class GameScene: SKScene {

override func didMoveToView(view: SKView) {
/* Setup your scene here */

scene!.scaleMode = SKSceneScaleMode.Fill //usually at GameViewController, not GameScene

square.xScale = nodeConstantWidth
square.yScale = nodeConstantHeight

square.anchorPoint = CGPointZero
square.position = CGPoint(x: screenWidth / 1.5, y: screenHeight / 1.5)
}
}
``````

``````import SpriteKit

class GameScene: SKScene {

override func didMoveToView(view: SKView) {
/* Setup your scene here */

scene!.scaleMode = SKSceneScaleMode.ResizeFill //usually at GameViewController, not GameScene

let square = SKSpriteNode(imageNamed: "square")
square.anchorPoint = CGPointZero
square.position = CGPoint(x: self.frame.width / 1.095, y: self.frame.height / 1.1875) //superior right on iPhone 5/5s
}
}
``````

the square isn't positioning at the same place on every device, only on the device where position was set up. I made a little comparison below.

Try mathematically setting the size. Use UIScreen.mainScreen().bounds.width and UIScreen.mainScreen().bounds.height to find the device size. Use a little math to set up a proportion between your .sks scene and the device's size. Then use node.setScale to set the scale of your Sprite

Here is some sample code. Declare these as universal constants:

``````// MARK: Screen Dimensions
let screenSize = UIScreen.mainScreen().bounds
let screenWidth = screenSize.size.width
let screenHeight = screenSize.size.height

// MARK: Node Sizes
let node = SKSpriteNode(imageNamed: "image")
let nodeConstantWidth = screenWidth/node.size.width*0.3
``````

If you were to move the declaration of nodeConstantWidth to GameScene, It will continually scale itself each time the scene is rendered. To avoid this, we just declare it once universally. Mathematically, the equation above will set the node's width to 30% of the screen's width on any device, and the height will be calculated accordingly. Change the '0.3' to any number to adjust this. Then in GameScene:

``````node.setScale(nodeConstantWidth)
``````
Source (Stackoverflow)