32

我刚刚开始了一个新的 Sprite Kit 项目来学习如何使用它。我观看并阅读了很多教程,但没有教程可以回答我的问题/问题。

我想为我的 iPhone 5S 创建一个应用程序。所以屏幕尺寸是1136x640。我为我的应用程序创建了一个 1136x640 背景图像。但是当我将图像添加到我的应用程序时,它会变得很大!iOS 模拟器只显示图像的中间。

有人能告诉我我必须使用什么屏幕尺寸,为什么?

非常感谢!

这是我从教程中复制的代码。代码在 initWithSize 方法的 myScene.m 文件中

        SKSpriteNode *background = [SKSpriteNode spriteNodeWithImageNamed:@"myBackground"];
    background.position = CGPointMake(CGRectGetMidX(self.frame),CGRectGetMidY(self.frame));

    [self addChild:background];

编辑

我在谷歌上搜索并发现了这个:

必须使用“viewWillLayoutSubviews”更改 viewDidLoad 方法。

这是这个方法:

    - (void)viewWillLayoutSubviews
    {
    [super viewWillLayoutSubviews];

    // Configure the view.
    SKView * skView = (SKView *)self.view;
    skView.showsFPS = YES;
    skView.showsNodeCount = YES;

    // Create and configure the scene.
    SKScene * scene = [MyScene sceneWithSize:CGSizeMake(skView.bounds.size.width*2,skView.bounds.size.height*2)];
    scene.scaleMode = SKSceneScaleModeAspectFill;

    // Present the scene.
    [skView presentScene:scene];
}

起初,场景 = MySceneWithSize 行是:

SKScene * scene = [MyScene sceneWithSize:skView.bounds.size];

但那时它只是 iPhone 5 屏幕尺寸 (568x320) 的一半。所以我不得不加倍大小。有人知道为什么吗?

4

9 回答 9

29

对您当前问题的简短回答:

background.size = self.frame.size;

长答案,以及关于其他方法的讨论......

该场景以逻辑单位工作,而不是物理像素(如其他帖子中所述)。

1 个逻辑单元在旧套件上通常为 1 个像素,在较新套件/iPad 上为 2 个像素。这可能在 5 年内达到 4 个像素。

在逻辑单元中工作可以保护您免受未来尺寸变化的影响,并且应该帮助程序员 - 尽管这经常使新手感到困惑。

让图像填充当前场景的最简单方法是将其大小设置为“逻辑单位”,无论它最初是什么大小。

这比使用 SKActions 更好(因为用户最终可能会看到它们,并且在操作完成之前不能依赖基于节点尺寸的任何计算),并且比缩放更好,因为缩放需要您知道原始图像尺寸。

你可以通过 size 属性来做到这一点,或者如果你真的想制作动画,可以通过一个动作来做到这一点。

在现场简直......

-(void)didMoveToView:(SKView *)view
{
    [super didMoveToView:view];

    SKSpriteNode* background = [SKSpriteNode spriteNodeWithImageNamed:@"myBackground"];
    background.size = self.frame.size;
    background.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
    [self addChild:background];
} 

或者,如果您的图像效果很好,例如在更高的分辨率上,您可以将图像重命名为 myBackground@2x.png,将其添加到您的项目中,您可能根本不需要调整大小,但您还需要对于较低分辨率的设备,将其缩小 50%,并将其保存为 myBackground.png。

我总是将导入图像的大小设置为我想要的逻辑单位(或屏幕尺寸的百分比)以保持我的理智。

于 2014-10-05T09:35:35.727 回答
9

我发现,如果图像的大小与您要创建的节点大小不同,则大小会有点有趣(例如在非视网膜设备上使用视网膜图像或图像命名不正确)。如果您从图像创建纹理并使用以下内容设置纹理和节点大小,则可以缩放图像以填充:

SKTexture *backgroundTexture = [SKTexture textureWithImageNamed:@"MyImage.png"];
SKSpriteNode *background = [SKSpriteNode spriteNodeWithTexture:backgroundTexture size:self.view.frame.size];
background.position = (CGPoint) {CGRectGetMidX(self.view.frame), CGRectGetMidY(self.view.frame)};
[scene addChild:background];

我不是 100% 确定这是否能解决您的问题,但它可能值得一试。

于 2013-11-30T21:19:07.707 回答
8

这条线以点为单位返回大小,而不是像素。这是因为不同的设备具有不同的分辨率,但点的大小相同。在非视网膜设备上,1 个点是 1 个像素,在视网膜设备上,1 个点是两个像素。这就是为什么你得到这个尺寸

SKScene * scene = [MyScene sceneWithSize:skView.bounds.size];

您不想将场景的大小加倍,因为它只是我们屏幕的边界,不可见。

于 2013-11-02T19:38:46.950 回答
7

您是否尝试在图像名称的末尾添加“@2x”?

于 2013-11-09T05:30:26.783 回答
3

我基本上按照上面的答案进行,但是我继续直接设置宽度和高度,这样我就不必担心它是否设置正确,当然我还需要检查是否有使用 iPhone4以获得完整的解决方案。

- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];

    // Configure the view.
    SKView * skView = (SKView *)self.view;
    if (!skView.scene) {
        skView.showsFPS = YES;
        skView.showsNodeCount = YES;

        CGSize tmpSize;
        tmpSize.width = 640;
        tmpSize.height = 1136;
        // Create and configure the scene
        SKScene * scene = [CreationScene sceneWithSize:tmpSize];

        scene.scaleMode = SKSceneScaleModeAspectFill;

        // Present the scene.
        [skView presentScene:scene];
    }
}
于 2014-03-24T00:42:18.747 回答
2

这对我有用。这可以吗?

//Set background image.
    SKSpriteNode *background = [SKSpriteNode spriteNodeWithImageNamed:@"myBackground.png"];
    background.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
    background.xScale = 0.5;
    background.yScale = 0.5;

    [self addChild:background];
于 2014-01-14T16:40:12.203 回答
2

解决方案:

将此代码放入您的 viewWillLayoutSubviews 中,而不是放入加载精灵的 UIViewController 的 viewDidLoad 中。

  - (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];

    // Configure the view.
    SKView * skView = (SKView *)self.view;
    if (!skView.scene) {
      skView.showsFPS = YES;
      skView.showsNodeCount = YES;

      // Create and configure the scene.
      SKScene * scene = [MyScene sceneWithSize:skView.bounds.size];
      scene.scaleMode = SKSceneScaleModeAspectFill;

      // Present the scene.
      [skView presentScene:scene];
    }
}

解释 :这将创建一个大小作为视图边界的场景。但是,当调用 viewDidLoad 时,这是在视图被添加到视图层次结构之前,因此它还没有响应布局更改。所以视图边界可能还不正确,这可能不是启动场景的最佳时间。

此答案复制自:http ://www.raywenderlich.com/42699/spritekit-tutorial-for-beginners 归功于 Ray :)。

我和你一样在我的 SKScene 中使用了相同的代码,但是如果没有这个解决方案 Ray 在 UIViewController 中提供,它会呈现场景,它将无法工作。

于 2014-03-14T13:30:58.493 回答
2

我确实使用和精灵作为背景。

    double escalax =        self.size.width/ sprite.size.width  ;
    double escalay =        self.size.height/ sprite.size.height  ;


    SKAction *mostrar = [SKAction scaleXTo:escalax y:escalay duration:0];

希望能帮助到你!

于 2014-05-05T17:48:44.807 回答
1

我和你有同样的问题。经过几天的谷歌搜索和尝试,我终于找到了这个问题的关键。您可以尝试多次更改scene.scaleMode ,直到获得满意的大小。我昨晚才发现这个,所以如果你想了解更多,这里有一个链接

https://developer.apple.com/library/ios/documentation/SpriteKit/Reference/SKScene_Ref/Reference/Reference.html#//apple_ref/doc/uid/TP40013024-CH1-DontLinkElementID_3

于 2014-08-29T02:29:34.167 回答