在Spritekit游戏中限制GUI元素的比例

GUI元素示例图像

因为邮件太多,我提前道歉,但是每个试图制作某种通用应用程序的人都知道这是非常有问题的东西,所以请对我轻松一点。

目标

我试图实现的(如上图所示)是在iPhone 5和iPhone 6上使用@ 2x资源,并保持应用程序的外观。 如果可能的话,要做到这一点,而不是手动计算基于检测到的设备的节点的比例和位置属性…所以总之,如何实现该应用程序自动约束元素(和场景)的比例? 另外,我希望在iPhone 6+上使用@ 3x资源来看应用程序,但由于简单,我只集中在iPhone 5和6上。

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

“为iPhone 6制作@ 2x资产的尺寸,然后iOS会自动为iPhone 5降尺度”。

但是在Spritekit场景中显然不是这样,或者我错过了一些东西。

问题

即使iPhone 6和iPhone 5具有相同的宽高比和相同的PPI,但使用相同的素材与场景大小(与第一张和第二张图片相比,与场景大小相比,看起来菜单精灵)看起来不会相同,因为PPI与像素密度和iPhone 6有更多的空间(更大的对angular线,更多的英寸),这意味着它有更多的像素比iPhone 5。这是我的问题来自哪里,我不知道是一个有效的方式来处理它。

我到目前为止所做的

第二个图像对于GUI来说不是问题,但对于游戏来说,就我而言,这是因为我希望在不同的设备上具有相同的外观和感觉。 只要看第一和第三的形象。

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

查看controller.m

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

所以在iPhone 6的尺寸上,场景总是有固定的大小,而且视图大小是根据设备而变化的。 我正在使用资产目录启动图像,而不是xib文件。 图片大小build议大小为640x960px 4s,640x1136px 5,750x1334px 6和1242×2208 6 +模式。 资产的大小适合iPhone 6,因此对于该型号,根本没有缩放比例。

与4s模型相关,当我使用上面描述的这种方法时,每边都有两个黑条。

到目前为止,我只在模拟器和iPhone 6设备上进行了testing(我在设备或模拟器上的第一个图像上看起来像是这样)。

现在,正如我所说的一切工作在iPhone 4s(有两个黑色的酒吧,因为不同的长宽比),5,6使用@ 2x资产,但如何使一切工作与iPhone 6 +使用@ 3x资产? 如果我使用375×667尺寸的场景,那么所有东西都被正确定位,并且具有良好的比例,但质量会受到影响(因为放大倍数为2x)

统一的GUI和游戏

据我所知,处理一个统一的graphics用户界面和游戏的最佳方法是设置你的场景大小(不pipe设备),并让SpriteKit从那里缩放。

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

这是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呢?

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

一个例子…

Spritekit – 不从SKTextureAtlas加载@ 3x图片

看来它在Xcode 6.2中也没有被修复。 如果你正在阅读这篇文章,想要@ 3x,那么可能值得向苹果公司提供一个雷达。 有一点需要注意的是,我没有看到文档中的任何地方都声称纹理地图集支持@ 3x(或者甚至@ 2x)。当它们被支持时,您不必对代码进行任何更改。 只需将@ 3x资产放入.atlas文件夹即可。

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

我的build议是不要担心,并运行@ 2x资产。 SpriteKit做一个体面的工作缩放图像,有很多的应用程序不支持@ 3x。 作为一个iPhone 6+的老板,这只是我现在所学的东西。 我希望苹果很快支持.atlas文件夹中的@ 3x图片。

警告

除了iPhone 6之外,您还要求所有设备都缩小比例(并扩大iPhone 6+)。在大多数情况下,您不应该注意到您的艺术(或testing中的性能)有很大差异,但是如您所知,你缩小图像,他们可能看起来有些不同。 另外还有4s的黑条问题,目前我还没有解决scheme。

closures点

如果设置场景大小并将场景设置为SKSceneScaleModeAspectFill则您将在所有设备上的应用中获得完全相同的外观和感觉,但是要求较老的设备缩小比例。 就我所见,它可以节省大量的时间和计划,并可以轻微的退缩。

希望对你的应用程序有帮助和好运。

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

我的解决scheme是编写你的代码,就好像你正在编写iPhone 6 plus。 使您的所有图像@ 3x大小和您的屏幕布局坐标为iPhone 6屏幕大小。

只需要一些代码,我就可以得到iPhone 6 plus,6,5和4屏幕尺寸的统一布局。 我已经包括每个人的屏幕截图。 字符图像是300×300。 2个button图像是100×100。

 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+

在这里输入图像说明

请注意,即使文本标签正确缩小,不仅字体大小,而且位置。

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

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