Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SkSpriteNode position in universal game

I'm creating universal game for all iOS devices in portrait mode using Swift. In GameViewController I'm creating scene like this:

let scene = GameScene(size:CGSize(width: 1536, height: 2048))
scene.scaleMode = .AspectFill

Background image has resolution 1536x2048, and so with above scaleMode on iPad it's displayed in its full size, on iPhone 6 1152x2048 is displayed with sides trimmed. Works perfectly fine on all devices, and only one background image is needed. Problem is that if I call for size.width or self.frame.size.width it always returns 1536, even if the actual visible area is e.g. 1152.

How can I set SkSpriteNode's position relative to visible area, so that it'll be for example 50x50 from the corner on every device?

like image 641
Adam Bardon Avatar asked Mar 20 '15 07:03

Adam Bardon


2 Answers

How can I set SkSpriteNode's position relative to visible area, so that it'll be for example 50x50 from the corner on every device?

The "visible area" is simply the view.

So you can make your positions relative to the view, and not the scene. I actually do this a lot in my game, which is universal and runs on both OS X and iOS.

In my case I typically do this for the user-interface, so I might have a scaled scene but I want to set some positions not relative to the scaled scene but relative to the visible area (i.e. the view).

To do this, you can write a function that converts view coordinates to the corresponding scene coordinates.

Here is my function that I use. Note that I subtract my desired y-position from height of view so that I can treat (0,0) as the bottom-left like sprite-kit does instead of the top-left like UIKit does.

func convert(point: CGPoint)->CGPoint {
    return self.view!.convert(CGPoint(x: point.x, y:self.view!.frame.height-point.y), to: self)
}

Here is an example of using this function:

self.node.position = convert(CGPoint(x: 50, y: 50)) 

This will always force the position of the node to be at (50,50) relative to the view (the visible portion of the screen) regardless of how your scene is scaled and sized.

like image 98
Epic Byte Avatar answered Nov 20 '22 09:11

Epic Byte


I don't think this is really the best approach. You should creating the GameScene based on SKView's size

let scene = GameScene(size: self.skView.bounds.size)

I don't think you should be setting one universal size for every device. You need to let the device set the scenes dimensions based on the screen's resolution. Then you need to be creating different images based on the device. 2x, 3x, 2x~ipad etc..

This tutorial is a good place to start: http://www.raywenderlich.com/49695/sprite-kit-tutorial-making-a-universal-app-part-1

like image 33
hamobi Avatar answered Nov 20 '22 08:11

hamobi