1

I am having trouble properly setting up my app so that it displays correctly on all devices. I want my game to look best for iPhone and I understand that setting my scene size using GameScene(size: CGSize(width: 1334, height: 750)) and use .aspectFill means that on iPads there will be less space to display things which I'm fine with. The problem is, how do I position my nodes so that they are relative to the each devices frame height and width? I use self.frame.height, self.frame.width, self.frame.midX, etc. for positioning my nodes and when I run my game, it positions things properly considering I run on my iPhone 6, but on my iPad, everything seems blown up and nodes are off the screen. I'm going crazy trying to figure this out

Brejuro
  • 3,421
  • 8
  • 34
  • 61

2 Answers2

1

I solved this in my game by using scaleFactors, numbers which tell my app how much to enlarge each length, width, height etc. Then I just make my game look well for one phone, and use that phone's width and height to calculate with which factor I need to enlarge it for other devices. In this example I use the iPhone 4 as a base, but you can use any device just change the numbers according to that device.

Portrait mode:

var widthFactor = UIScreen.main.bounds.width/320.0 //I divide it by the default iPhone 4 width
var heightFactor = UIScreen.main.bounds.height/480.0

Landscape mode:

var widthFactor = UIScreen.main.bounds.width/480.0 //I divide it by the default iPhone 4 landscape width    
var heightFactor = UIScreen.main.bounds.height/320.0

Then when you make a node, a coin image for example, multiply its coordinates or width/height by the scaleFactors:

let coin = SKSpriteNode(imageNamed: "coin")
coin.position = CGPoint(x: 25 * widthFactor, y: self.size.height - 70 * heightFactor)
Eric
  • 1,210
  • 8
  • 25
  • This seemed to get some nodes on the screen but they're still not positioned correctly. For example if I put a node at x:200 and y:200, on the iPhone it looks correct but on the iPad it now looks something like x: 200 and y: 400. I need it to look the same on both devices – Brejuro Jun 24 '17 at 16:08
  • i changed my answer, did you multiply the `x` with the `widthFactor`, and the `y` with the `heightFactor`? – Eric Jun 24 '17 at 16:13
  • Yeah, but my app is landscape so I swapped the width and height, correct? – Brejuro Jun 24 '17 at 16:14
  • No that won't be correct I think, as the Screen.bounds.width and height change according to orientation if I'm not mistaken. Could you try it without doing that? – Eric Jun 24 '17 at 16:16
  • I edited my question again, if you use the landscape one and then make sure everything looks good on your base model, it should look well on all devices – Eric Jun 24 '17 at 16:23
  • It doesn't work without doing that, because then the scales are all messed up on the base device. But doing it with swapping doesn't seem to work either because on the iPad it's still not positiong the node correctly – Brejuro Jun 24 '17 at 16:24
  • what base device do use use? because on that device the scaleFactors will both be 1, so you must just place the objects correctly there first. – Eric Jun 24 '17 at 16:26
  • I'm using an iPhone 6, and when I print the scales they are both 1.0 so I know that part is correct. I want to put a button on the bottom left corner, say 150x150, but on the ipad after applying the scales, it not on the bottom left corner – Brejuro Jun 24 '17 at 16:29
  • could you maybe paste the exact code for that button and your scaleFactors inside an edit? – Eric Jun 24 '17 at 16:34
  • I accidently deleted before you posted this comment because it didn't seem like it was working, but it was exactly what you had but for iPhone 6. I'm so beyond frustrated with this! I think I'm going to just use .aspectFit and have black lines on the iPad and call it a day – Brejuro Jun 24 '17 at 16:56
  • Well this can at least help you on iPhone scaling because it does work there, my game is only for phones so I wasn't sure about iPads but I thought it would work – Eric Jun 25 '17 at 14:36
1

I think what you're looking for might be in this answer: https://stackoverflow.com/a/34878528/6728196

Specifically I think this part is what you're looking for (edited to fit your example):

if UIDevice.current.userInterfaceIdiom == .pad {
   // Set things only for iPad

   // Example: Adjust y positions using += or -=
   buttonNode.position.y += 100
   labelNode.position.y -= 100
}

Basically, this just adds or subtracts a certain amount from the iPhone position if the user is using an iPad. It's not too complicated, and you can increase or decrease both x and y values of position by a certain value of percentage of the screen (self.size.width * decimalPercentage).

Another benefit of using this way is that you're just modifying the iPhone positions, so it starts by using the default values that you set. Then if on iPad, it will make changes.

If this is hard to understand let me know so I can clear up the explanation

Nik
  • 1,664
  • 2
  • 14
  • 27