Swift Spritekit Get Visible Frame Size

Swift SpriteKit get visible frame size

Adding this bit of code to the GameViewController seems to have fixed the issue.

            /* Set the scale mode to scale to fit the window */
scene.scaleMode = .AspectFill
scene.size = skView.bounds.size
skView.presentScene(scene)

Thank you @ABakerSmith for pointing me in the right direction.

SpriteKit - Getting the actual size/frame of the visible area on scaled scenes .AspectFill

Here is how Aspect Fill works:

The dimensions of your scene will always remain the same, so if you say your scene is 480 points by 800 points, it will always remain that way regardless of device.

What then happens is it will scale the scene starting from the center of the SKView until it fills the farthest walls.

This will in turn crop your scene.

So when designing your game across the different aspect ratios, you will need to design your game to handle cropping.

Now in your particular case, You will need to figure out what the aspect ratio is for the device, and work off the difference from the scene aspect.

E.G. Your scene is 3x5, device is 9x16, This means your device is going to grow to become 9.6x16 to fill up to the size of your 9x16 device. We get this because our height has more distance than our width, so we need to do 3/5 = a/16, 3*16 = a * 5, (3*16)/5 = a so a = 9.6.

This means you have .6 of cropping to your scene on the width, .3 on both edges.

Now you are going to ask, How does the .3 relate to the various screen sizes.

Well we need to figure out what percentage .3 is of 9.6. We do that with division, .3/9.6 = .03125 or 3.125%; This means we need to push our border in 3.125% in the scene's width, which is 15 points. That means .03125 * 480 = 15. Your borders should then start at 15 width and at 465.

Pseudo Code:

let newSceneWidth = (scene.width * view.height) / (scene.height)
let sceneDifference = (newSceneWidth - view.Width)/2
let diffPercentage = sceneDifference / (newSceneWidth)

let leftEdge = diffPercentage * scene.width;
let rightEdge = scene.width - (diffPercentage * scene.width);

Now if there is more distance to scale in the height than the width, you would have to swap the width and height variables.

SKSpriteNode with a size relative to the screen

So for anyone else has a similar issue the problem was that my scene was loaded from an SKS file.

The SKS file in question had it's size set to freeform. Changing this to a specific device e.g iPhone 6 and making sure the orientation was set to landscape has fixed the issues with sizing

SpriteKit - Can't understand what size to make background

When dealing with scenes for Sprite Kit, try not to focus on the screen size, because screen size is no longer a factor (now this is not 100% absolute fact, this is a general rule to go by)

Instead, treat your SKScene as if it was a virtual screen. The size of your SKScene is the "resolution" of your SKScene, and the OS will work in the background to figure out how to convert 1 virtual pixel (From here on out we will call point) to screen pixels( referred to here on out as pixels)

Now there is only 1 special case where the OS will change the resolution (scene size) to match the screen, and that is .resizeFill The other 3 will never change resolution on you.

.aspectFill and .aspectFit will ensure that your point to pixel conversion keeps and equal width and height (e.g. 1 point could equal 4x4 pixels) The only difference is .aspectFill will expand to fill the entire screen, meaning that excess points will be rendered outside the native screen bounds [ so (0,0) may lie 20 pixels left of the left most pixel, thus not being visible] and .aspectFit will fill till it hits a screen border, leaving black bars to fill the unused pixels.

Now .fill does not keep and equal width and height point to pixel ratio, and in the case of a 4:3 going to a 16:9 screen, you will notice that your point to pixel will be 5:4 because a 16:9 screen is 25% wider than a 4:3. This gets you the fatty effect.

So when dealing with your game you need to figure out the desired effect. If you set your scene size to 1024x768, then all non retina iPads will have a 1:1 pixel to point ratio, where retina has 2:1 pixels to point ratio. For an iphone 5, you would get roughly 1.14 pixels to every point (iphone is 1168 and your scene is 1024, so you do 1168/1024) then of the 768, you would be loosing 25%, because the ipad is 25% taller than an iphone in landscape. This means only 576 points will be showing, and the rest are in invisible screen space.

Basically, you can never get a 1:1 with both an iPad and an iPhone doing a universal app because you are working with 2 different aspect ratios. You are going to have to make 2 different sets of assets, or take some creative liberties that doesn't alter the gaming experience. This depends entirely on the game and unfortunately nobody will be able to answer it till they have an understanding of your game.

SpriteKit: SKShapeNode.calculateAccumulatedFrame returns a frame, which is bigger than its content

I believe the issue you are dealing with is that if you have a strokeColor defined, that border stroke adds to size of the rectangle.

Try this code :

SKShapeNode *rect = [SKShapeNode shapeNodeWithRect: CGRectMake(0, 0, 200, 100)];
rect.strokeColor = nil;

You have to look at the stroke as being additive, and adding to the dimensions of your shape.

How do you tell if a node is on the screen spritekit swift

You can use the following to test if a node is in the scene:

if (!intersectsNode(sprite)) {
println("node is not in the scene")
}

This assumes that self is an SKScene subclass, such as GameScene.

Sprite appearing in node count but not visible

I assume that the background node size is just the same as the image size. I also assume that the scene size is the same as the image size. If that's the case, try the following.

let backTexture = SKTexture(imageNamed: "background")
let background = SKSpriteNode(texture: backTexture)
//background.size = CGSize.init(width: (self.scene?.size.width)!, height: (self.scene?.size.height)!)
//background.anchorPoint = self.anchorPoint
background.position = CGPoint(x: CGFloat(i) * background.size.width, y: 0))


Related Topics



Leave a reply



Submit