1

I need to display a few images in my IOS Application. What should I do so that the images display appropriately across all devices?

Do I have to set the size of the image manually based on the device? Please clarify.

Mecki
  • 125,244
  • 33
  • 244
  • 253
py_ios_dev
  • 487
  • 1
  • 7
  • 19

2 Answers2

2

You wouldn't use SpriteKit just to display images. You would load the images as UIImage and then create a UIImageView that you can place on the screen wherever and however you want and then you just assign the UIImageView your UIImage. UIImageView has a lot of properties you can set how images are displayed (e.g. if they are scaled and how they are scaled or if they are not scaled, how they shall be aligned within the viewable area, and so on). You can draw a UIImageView on top of a SpriteKit scene, that is no problem on iOS (on iOS everything is drawn by OpenGL ES or Metal anyway).

Of course you can also embed any image as a sprite if you like:

UIImages * img = ...;
SKTexture * tex = [SKTexture textureWithImage:img];
SKSpriteNode * sprite = [[SKSpriteNode alloc] initWithTexture:tex];
// If you don't use ARC, I'd add the following below:
// [sprite autorelease];

Now you can perfectly integrate it into the scene in whatever way you like an perfectly align it will all your other sprites. Yet if you just want to paint an image over the scene:

SKScene * scene = ...;
SKView * sceneView = scene.view;

UIImageView * imgView = [[UIImageView alloc] init];
imgView.image = img;
// Whatever content mode you prefer
imgView.contentMode = UIViewContentModeScaleAspectFit;
// Where shall it be placed and how big shall it be.
imgView.frame = CGRectMake(posX, posY, width, height);
// If you'd use this, it will cover the whole scene: 
// imgView.frame = sceneView.frame;

// Add it on top of your scene
[[sceneView parent] addSubview:imgView];

// If you don't use ARC, don't forget to release it:
// [imgView release];

If you load an UIImage from your application bundle with [UIImage imageNamed:@"blah"] and the image exists in different resolutions for retina devices (blah.png, blah@2.png, blah@3.png), the system will automatically load the image it considers most suitable for the screen of the current device. This is nothing you have to deal with.

If you need to convert between scene coordinates and view coordinates, SKScene offers -convertPointFromView: and -convertPointToView: for this case. If the scene fills the whole screen, then these actually convert between scene and screen coordinates.

Even if devices have different resolutions, your scene can always have the same "virtual size". So you can always say that the scene is 400x300, no matter what the real screen resolution is. In that case placing a sprite of virtual dimension 200x150 at the virtual coordinates (100,75) will always center it on the screen, no matter what device or how big the screen really is (well, assuming that the SKSceneView really covers exactly the whole screne, of course). The size of a SKScene is just the coordinate system you want to have for layouting your game, it can be whatever you want it to be, it can be bigger or smaller than the real screen.

The scene is always drawn into a SKSceneView. The size of the SKSceneView is the real size of your scene in screen coordinates. So if you SKScene is 480x320 and the size of the SKSceneView is 1440x960, then moving a sprite one pixel in your scene will in fact move it 3 pixels on the screen. Yet if your SKScene is 1136x640, but your SKSceneView is only 586x320, then moving a sprite two pixels in your scene will only move it one pixel on screen. Your scene is always scaled up or down as required.

Personally I'd either stick with the same size across all devices or maybe just make two or three device classes but not adopt the game for every single device and every existing screen resolution.

Mecki
  • 125,244
  • 33
  • 244
  • 253
  • In the game that I am developing using Spritekit, would you recommend me using the UIImage / UIImageView? – py_ios_dev Dec 05 '15 at 01:49
  • @adf_mobile_developer Depends on how you want to display the images. Fullscreen over the whole screen or embedded into the game content? – Mecki Dec 05 '15 at 01:50
  • embedded into the game content. not the whole screen. – py_ios_dev Dec 05 '15 at 01:52
  • @adf_mobile_developer Please be more detailed how the images will be part of the game scene. How will this image be different from just another sprite in the scene? – Mecki Dec 05 '15 at 01:54
  • the size of the screen is different across different devices. so, do I specify the size of image based on the device manually? Is there an easier way to do this? Thanks in advance. – py_ios_dev Dec 05 '15 at 01:58
  • @adf_mobile_developer If the images integrate with the scene as you said before, the screen size is irrelevant, as you need to always integrate it the same way into the scene (it need to fit the scene sizes and not the screen sizes). If you just paint it "over the scene" and it only depends on screen size and not on scene size, then you don't want to integrate into the scene, than you just want to use an an UIImageView and paint it over the scene in whatever size you want. – Mecki Dec 05 '15 at 02:06
  • 1
    I would recommend not using UIKit for creating SKSpriteNodes SKSpriteNode * sprite = [SKSpriteNode spriteNodeWithImageNamed:@"yourImageName"]; No UIKit need. – Skyler Lauren Dec 05 '15 at 02:26
  • Appreciate your time and inputs. I now understand the difference between integrating an image on the scene versus painting an image over the scene. I should integrate the image on the scene in my application. However, I don't understand when you say that the screen size is irrelevant as I need to integrate the image the same way onto the scene. Do you mind explaining it? – py_ios_dev Dec 05 '15 at 02:27
  • @adf_mobile_developer If you have a sprite of a dog in your scene and you paint the image next to it, should the image really depend on the size of the screen? Shouldn't it depend on the size of the dog? Or do you want it depend on the physical size of the image, as the image must not be zoomed in or out? – Mecki Dec 05 '15 at 02:32
  • Yes, the image size should depend on the size of the adjacent sprites. So, what do you suggest? – py_ios_dev Dec 05 '15 at 02:44
  • @adf_mobile_developer I don't really understand your problem. Then why don't you just treat the image like another sprite and place it into the scene as you do with all the other sprites, that are all images as well. Just load the image into a texture, make a sprite node and then place it into your scene. You can adjust the size of a sprite node by setting a property and if the sprite is half the size of the scene size, it will half of the screen for example. Otherwise just derive its size from other sprites in your scene (if it hall be twice the size of the dog, make it twice the size). – Mecki Dec 05 '15 at 02:52
  • @Mecki Thank you! I understand it now. Appreciate all your help. – py_ios_dev Dec 05 '15 at 02:55
2

There a lot of things to consider when dealing with images in SpriteKit, The short answer is you should be creating images in 1x, 2x, and 3x (background.png, background@2x.png and background@3x.png). You will get the best image quality if you do that.

As far as resizing images based on different devices that usually is done at the scene level. There are a lot of good SO questions out there that cover a lot of the questions you will have.

For example: Dealing with different iOS device resolutions in SpriteKit

I recommend searching for "creating a universal app with SpriteKit".

Hopefully that answers your immediate question and helps get you started with the other questions you will have.

Community
  • 1
  • 1
Skyler Lauren
  • 3,792
  • 3
  • 18
  • 30
  • I am already creating images using 1x, 2x, 3x resolutions. Based on my conversation with mecki below, I also understand that I should integrate my images in the scene. Hard-coding the image size using CGSize is not appropriate since the scene size is equal to screen size. – py_ios_dev Dec 05 '15 at 02:47
  • @adf_mobile_developer Your scene size isn't necessary your screen size. It really depends on how you create your scene. If you use Apple's default project you will notice that the Scene is actually much larger than the view/screen size if you use an iPhone (scene was 1024 x 768) but it gets scaled down using SKSceneScaleModeAspectFill and it scales the scene down when used on a phone. – Skyler Lauren Dec 05 '15 at 02:52