在Spritekit游戏中约束GUI元素的比例

Whi*_*ind 6 size sprite universal ios sprite-kit

GUI元素示例图像

我之前因为篇幅很大而道歉,但是每个试图制作某种通用应用程序的人都知道这是非常有问题的东西,所以请对我很轻松......

目标

我想要实现的目标(如上图所示)是在iPhone 5和6上使用@ 2x资源,并保持应用程序的外观相同.并且如果可能的话,在没有基于检测到的设备手动计算节点的比例和位置属性的情况下完成所有这些...简而言之,如何实现该应用程序自动约束元素(和场景)之间的比例?另外,我想在iPhone 6+上使用@ 3x资产看一眼应用,但由于简单,我只专注于iPhone 5和6.

我在网上发现的是有些人说这个(下采样)是由iOS自动完成的,例如他们建议:

"为iPhone 6制作大小为@ 2x的资产,然后iOS将自动为iPhone 5进行缩减".

但是当谈到Spritekit场景时,这显然不是真的,或者我遗漏了一些东西.

问题

即使iPhone 6和iPhone 5具有相同的宽高比和相同的PPI,使用相同的资产与场景尺寸(第1和第2图像上的外观菜单精灵与场景尺寸相比)看起来也不一样,因为PPI与像素密度,iPhone 6有更多的空间(更大的对角线,更大的英寸),这意味着它有比iPhone 5更多的像素.这是我的问题的来源,我不知道什么是一个有效的方法来处理它.

到目前为止我做了什么

第二个图像不是GUI的问题,但对于游戏玩法,在我的情况下是,因为我想在不同的设备上具有相同的外观和感觉.只看第一和第三张图片.

感谢Skyler Lauren的建议,我已经设法在7.1或8.1系统以及iPhone 6上的所有iPhone 5设备上看到相同的应用程序.所以现在,问题是如何使这个代码适用于iPhone 6 +使用@ 3x纹理,以及iPhone 4s.这是iPhone 5和6的解决方案:

查看controller.m

GameScene *scene = [GameScene sceneWithSize:CGSizeMake(375,677)];//fixed instead of view.bounds.size
 scene.scaleMode = SKSceneScaleModeAspectFill;
Run Code Online (Sandbox Code Playgroud)

所以场景总是在iPhone 6尺寸上具有固定尺寸,并且视图尺寸根据设备而变化.我正在使用资产目录来启动图像而不是xib文件.图像尺寸为推荐尺寸 - 640x960px 4s,640x1136px 5,750x1334px 6和1242x2208 6 +型号.资产的大小适合iPhone 6,因此对于该型号,根本没有缩放.

与4s模型相关,当我使用上述方法时,每侧有两个黑条......

到目前为止,我只在模拟器和iPhone 6设备上测试了这一点(我看到在设备或模拟器上的第一张图像上看起来像).

就目前我所说的一切都适用于iPhone 4s(由于不同的宽高比而有两个黑条),5,6使用@ 2x资产,但如何使用@ 3x资产使iPhone 6+一切正常?如果我使用375x667尺寸的场景,那么一切都正确定位并具有良好的比例,但质量受损(因为升级@ 2x)

Sky*_*ren 5

统一的GUI和游戏

据我所知,处理统一GUI和游戏的最佳方法是设置场景大小(无论设备如何),让SpriteKit从那里扩展.

GameScene *scene = [GameScene sceneWithSize:CGSizeMake(375,677)];//fixed instead of view.bounds.size
scene.scaleMode = SKSceneScaleModeAspectFill;
Run Code Online (Sandbox Code Playgroud)

这是iPhone 6的分数.因为SpriteKit在点上工作但是设备以像素显示,对于@ 2x设备,场景大小将是750px x 1354px像素,对于iPhone 6+,场景大小将是1125px x 2031px(该设备以像素为单位实际为1080 x 1920).

这如何与资产一起使用?

那么它在.atlas文件夹中的1x和2x资产上工作得相当好.再次因为所有内容都转换为点,你可以在纹理图集中使用button.png和button@2x.png,并且所有iPhone的定位都相同并且看起来相同.

@ 3x怎么样?

对于Apple来说,这是一个更好的问题.显然,SpriteKit不支持纹理图集中的@ 3x图像.SO上已经有一些问题试图解决这个问题.

一个例子......

Spritekit - 不从SKTextureAtlas加载@ 3x图像

似乎它还没有在Xcode 6.2中修复.如果你正在读这篇文章并想要@ 3x,那么可能值得用Apple提交雷达.有一点需要注意的是,我没有看到文档中的任何地方声称纹理地图集被认为支持@ 3x(或者甚至是@ 2x)当支持它们时,您不必对代码进行任何更改.只需将@ 3x资源放入.atlas文件夹即可.

我可以/应该对@ 3x资产做些什么?

我的建议是不要担心它并运行@ 2x资产.SpriteKit在缩放图像方面做得不错,有很多不支持@ 3x的应用程序.作为iPhone 6+的拥有者,这是我现在学会了的东西.我希望Apple很快支持.atlas文件夹中的@ 3x图像.

警告

您要求所有设备都缩小,但iPhone 6除外(并扩展iPhone 6+)在大多数情况下,您不应该注意到您的艺术(或我的测试的性能)有很大差异,但正如您所知道的那样你缩小图像,他们可能看起来略有不同.4s上还有黑条问题,目前我还没有解决方案.

结束点

如果您设置场景大小并将场景设置为" SKSceneScaleModeAspectFill但是要求旧设备缩小",您将在所有设备的应用程序中获得完全相同的外观.据我所知,它节省了大量的时间和计划,并有轻微的退缩.

希望这对您的应用程序有所帮​​助并带来好运.


san*_*ony 5

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

我的解决方案是编写代码,就像编写iPhone 6 plus一样.为iPhone 6屏幕尺寸制作所有图像@ 3x尺寸和屏幕布局坐标.

只需一点代码,我就可以获得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];
}
Run Code Online (Sandbox Code Playgroud)

iPhone 4

在此输入图像描述

iphone 5

在此输入图像描述

iPhone 6

在此输入图像描述

iPhone 6+

在此输入图像描述

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

作为参考,我确实使用了GameViewController中的标准代码,因为我发现使用更简单的版本更容易.这是我用来呈现我的SKView的代码:

- (void)viewDidLoad {
    [super viewDidLoad];

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