【问题标题】:dealing with different screen sizes in xcode在 xcode 中处理不同的屏幕尺寸
【发布时间】:2015-05-11 07:34:37
【问题描述】:

我有一款 iPhone 游戏,最初是为 iPhone 6 开发的,在 iPhone 5 sim 上玩时效果很好,但在 iPhone 4 sim 上玩时,两边都被拉长了?!?我从左侧和右侧生成的节点在屏幕上生成,而不是像在 iPhone 6 和 5 上那样在屏幕外生成。 (请不要说这是重复的,因为我一直在寻找如何处理不同 iPhone 的几个星期)

我在 y 轴上随机生成左右方向的箭头。它们在屏幕外生成,然后在屏幕上缓慢移动,而不是在屏幕上快速移动,但在 iPhone 4 上,箭头会在屏幕上生成。这是其中一个箭头的代码

-(void) leftArrow
{
    int randomY = arc4random() % (675 - 175);
    int yPoint = randomY + 175;
    leftArrow = [SKSpriteNode spriteNodeWithImageNamed:@"arrow"];

    leftArrow.size = CGSizeMake(leftArrow.size.width/1.2, self.frame.size.height/22);
    leftArrow.position = CGPointMake(CGRectGetMidX(self.frame) - 230, yPoint);
    leftArrow.zPosition = 50;
    leftArrow.alpha = 1;

    SKAction* action1 = [SKAction moveToX:leftArrow.position.x + 30 duration:0.5];
    SKAction* wait = [SKAction waitForDuration:0.75];
    SKAction* action2 = [SKAction moveToX:leftArrow.position.x + 470 duration:1.5];
    SKAction* sequence = [SKAction sequence:@[action1,wait,action2,destroy]];

    [self addChild:leftArrow];
    if (deadDown == 1 || deadUp == 1 || didIntersect == true)
    {
        [leftArrow runAction:destroy];
    }
    else
    {
        [leftArrow runAction:sequence completion:^{
            if (ii != 1)
            {
                if (didIntersect != true)
                {
                    score++;
                    if (score == 100)
                    {
                        backgroundScore.fontSize = 300;
                        backgroundScore.position = CGPointMake(backgroundScore.position.x, backgroundScore.position.y + 30);
                }
                strFromInt = [NSString stringWithFormat:@"%d",score];
                backgroundScore.text = strFromInt;
                }
            }
        }];
    }
}

我也在 didmovetoview 函数中使用它

self.scaleMode = SKSceneScaleModeAspectFill;

【问题讨论】:

  • 能否提供 iPhone 4 和 iPhone 5 的屏幕截图?所以,我可以看到可能导致拉伸的原因。您是否使用过自动布局来管理不同的屏幕尺寸?
  • 我愿意,但我的名声太低了

标签: ios objective-c iphone sprite-kit


【解决方案1】:

主要问题是处理与图像资源和屏幕对象坐标相关的各种屏幕尺寸。

我的解决方案是像为 iPhone 6 plus 编写代码一样编写代码。将您的所有图像设置为@3x 大小,并将您的屏幕布局坐标设置为 iPhone 6 屏幕大小。

只需一点代码,我就能为 iPhone 6 plus、6、5 和 4 屏幕尺寸获得统一的布局。我已经为每个人提供了屏幕截图。字符图像为 300x300。 2 个按钮图像为 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

注意文本标签是如何正确缩小的,不仅是字体大小,还有位置。

您也可以使用上述逻辑来生成与屏幕大小相关的节点。

供您参考,我确实在 GameViewController 中使用了标准代码,因为我发现使用更简单的版本更容易。这是我用来展示我的 SKView 的代码:

- (void)viewDidLoad {
    [super viewDidLoad];

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

【讨论】:

  • 这可行,但该死的现在我必须重新排列和缩放我所有的节点哈哈谢谢
  • 另一件事。这适用于宽度,但是当我开始但当我在 iPhone 4 上运行应用程序时,它会切断顶部和底部???
  • 而且还真的放大了,可以缩小场景吗??
  • @siqhakz - 我很抱歉。我刚刚意识到我没有为我的答案添加相关代码。请用代码查看编辑后的答案。
【解决方案2】:

在从 iPhone 5 或 6 升级到 4 时,屏幕纵横比从 16:9(5 和 6)变为 4:3(iPhone 4)。您的选择是使用 SKSceneScaleModeAspectFill(您是)或 SKSceneScaleModeAspectFit,而不会出现图像失真。来自 Apple 文档:

SKSceneScaleModeAspectFill "....这保证了视图的整个区域都被填充,但可能会导致部分场景被裁剪。"

SKSceneScaleModeAspectFit "..... 这保证了整个场景都是可见的,但可能需要在视图中设置信箱。"

我遇到了类似的问题,并为 4:3 设备(iPhone 4/iPad)重新创建了单独的图像,因为上述 2 个选项都没有满足我的需求。

【讨论】:

    【解决方案3】:

    尝试使用比例而不是实际尺寸。所有 iOS 设备都有不同的宽度和高度。

    改变这个

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

    这样的事情

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

    我只能猜测它应该做什么,但尝试改变它

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

    到这里:

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

    我也建议你改变这些:

    改变那些“30”和“470”

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

    【讨论】:

    • 嘿,我可以看到使用比例是如何工作的,但它仍然会产生远离屏幕的方式,当我将 / 2 更改为 / 3.8 时,它适用于 iPhone 4,但对于 iPhone 6,它会进一步产生它离开屏幕。我应该使用特定的锚点还是?
    • 试试这个:leftArrow.position = CGPointMake(-self.frame.size.wight / 2 - leftArrow.frame.size.width / 2, yPoint); 什么的像这样:leftArrow.position = CGPointMake(-self.frame.size.wight / 2 - self.frame.size.width / 10, yPoint);
    • 这些都不起作用。我认为这是因为场景比我们看到的要大得多,将某些东西放在屏幕的 0,0 位置而不是底角。
    猜你喜欢
    • 2015-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-18
    • 2012-10-13
    相关资源
    最近更新 更多