dealing with different screen sizes in xcode

给你一囗甜甜゛ 提交于 2019-12-09 04:52:26

The main issue is handling the various screen sizes in relation to your image assets and screen object coordinates.

My solution is to write your code as if you are coding for the iPhone 6 plus. Make all your images @3x size and your screen layout coordinates for the iPhone 6 screen size.

With just a bit of code I was able to get an uniform layout for the iPhone 6 plus, 6, 5 and 4 screen sizes. I have included screen shots for each one. The character image is 300x300. The 2 button images are 100x100.

static const float kIphone6PlusScaleFactorX = 1.0;
static const float kIphone6PlusScaleFactorY = 1.0;
static const float kIphone6ScaleFactorX = 0.9;
static const float kIphone6ScaleFactorY = 0.9;
static const float kIphone5ScaleFactorX = 0.772;
static const float kIphone5ScaleFactorY = 0.772;
static const float kIphone4ScaleFactorX = 0.772;
static const float kIphone4ScaleFactorY = 0.652;

#import "GameScene.h"

@implementation GameScene {
    float scaleFactorX;
    float scaleFactorY;

    SKSpriteNode *node0;
    SKSpriteNode *node1;
    SKSpriteNode *node2;
    SKLabelNode *label0;
}

-(void)didMoveToView:(SKView *)view {
self.backgroundColor = [SKColor blackColor];

    if(view.frame.size.height == 736) {
        NSLog(@"iPhone 6 plus");
        scaleFactorX = kIphone6PlusScaleFactorX;
        scaleFactorY = kIphone6PlusScaleFactorY;
    }
    if(view.frame.size.height == 667) {
        NSLog(@"iPhone 6");
        scaleFactorX = kIphone6ScaleFactorX;
        scaleFactorY = kIphone6ScaleFactorY;
    }
    if(view.frame.size.height == 568) {
        NSLog(@"iPhone 5");
        scaleFactorX = kIphone5ScaleFactorX;
        scaleFactorY = kIphone5ScaleFactorY;
    }
    if(view.frame.size.height == 480) {
        NSLog(@"iPhone 4");
        scaleFactorX = kIphone4ScaleFactorX;
        scaleFactorY = kIphone4ScaleFactorY;
    }

    node0 = [SKSpriteNode spriteNodeWithImageNamed:@"Pic"];
    node0.position = CGPointMake(self.size.width/2, self.size.height/2);
    [node0 setScale:scaleFactorX];
    [self addChild:node0];

    node1 = [SKSpriteNode spriteNodeWithImageNamed:@"button0"];
    node1.position = CGPointMake(100*scaleFactorX, 100*scaleFactorY);
    [node1 setScale:scaleFactorX];
    [self addChild:node1];

    node2 = [SKSpriteNode spriteNodeWithImageNamed:@"button1"];
    node2.position = CGPointMake(314*scaleFactorX, 100*scaleFactorY);
    [node2 setScale:scaleFactorX];
    [self addChild:node2];

    label0 = [SKLabelNode labelNodeWithFontNamed:@"HelveticaNeue-Bold"];
    label0.text = @"Big Game Menu";
    label0.fontSize = 48*scaleFactorX;
    label0.fontColor = [SKColor whiteColor];
    label0.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeCenter;
    label0.verticalAlignmentMode = SKLabelVerticalAlignmentModeCenter;
    label0.position = CGPointMake(207*scaleFactorX,690*scaleFactorY);
    [self addChild:label0];
}

iPhone 4

iPhone 5

iPhone 6

iPhone 6 Plus

Notice how even the text label is scaled down correctly not just by font size but also location.

You can use the above logic to also spawn nodes in relation to the screen size.

For your reference, I did use the standard code in my GameViewController because I find it easier to work with a simpler version. This is the code I used to present my SKView:

- (void)viewDidLoad {
    [super viewDidLoad];

    SKView * skView = (SKView *)self.view;
    SKScene *scene = [GameScene sceneWithSize:skView.bounds.size];
    scene.scaleMode = SKSceneScaleModeAspectFill;
    [skView presentScene:scene];
}

In moving from iPhone 5 or 6 to 4 there is a change in screen aspect ratio from 16:9 (5 and 6) to 4:3 (iPhone 4). Your options, without image distortion, are to either use SKSceneScaleModeAspectFill (which you are) or SKSceneScaleModeAspectFit. From Apple docs:

SKSceneScaleModeAspectFill "....This guarantees that the entire area of the view is filled but may cause parts of the scene to be cropped."

SKSceneScaleModeAspectFit "..... This guarantees that the entire scene is visible but may require letterboxing in the view."

I ran into a similar issue and recreated separate images for a 4:3 device (iPhone 4/iPad) because neither of the above 2 options gave me what I wanted.

Try using proportions instead of actual sizes. All iOS devices have different widths and height.

Change this

leftArrow.position = CGPointMake(CGRectGetMidX(self.frame) - 230, yPoint);

To something like this

leftArrow.position = CGPointMake(CGRectGetMidX(self.frame) - self.frame.size.width / 2, yPoint);

I only can guess what it should do, but try changing this

int randomY = arc4random() % (675 - 175);
int yPoint = randomY + 175;

To this:

int randomY = arc4random() % (self.frame.size.height - self.frame.size.height / 4);
int yPoint = randomY + self.frame.size.height / 4;

Also i would recomend you to change these:

change those "30" and "470"

SKAction* action1 = [SKAction moveToX:leftArrow.position.x + 30 duration:0.5];

SKAction* action2 = [SKAction moveToX:leftArrow.position.x + 470 duration:1.5];
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!