【问题标题】:Sprite Kit texture sizes / resolutionSprite Kit 纹理大小/分辨率
【发布时间】:2026-02-04 22:15:02
【问题描述】:

我刚开始使用 Sprite Kit,但在加载纹理精灵时遇到了问题。

我在 Xcode 中使用 Sprite Kit 模板创建了一个新项目,并想添加一个带有图像文件作为纹理的简单精灵。这是我在场景的 init 方法中使用的代码:

SKSpriteNode *myNode = [SKSpriteNode spriteNodeWithImageNamed:@"my_image_file"];
myNode.position = CGPointMake(100, 100);
[self addChild:myNode];

我没有在图像名称中添加扩展名,因此我的文件名为“my_image_file.png”,但我在末尾省略了.png。正如许多教程中所建议的,我还将场景创建移至 viewWillLayoutSubviews 方法。

我在模拟器中运行了这个项目(使用视网膜 iPhone 作为设备),令我惊讶的是,精灵看起来是我预期的两倍,而且像素也很大。看起来好像我使用的是非视网膜 iPhone。据我所知,Apple Adventure 示例应用程序使用相同的命名约定,并且精灵在那里显示得很好。

我将我的文件重命名为“my_image_file@2x.png”,一切正常,精灵出现在我期望的视网膜显示器上。由于我有很多图像文件,我不想全部重命名它们,而且在没有 @2x 后缀的 Apple Adventure 应用程序中一切正常。

如果我在 SKSpriteNode 上使用此方法明确定义纹理的大小,它也可以正常工作:

+ (instancetype)spriteNodeWithTexture:(SKTexture *)texture size:(CGSize)size

我在每次运行之间清理了项目并从模拟器中删除了应用程序,所以我认为这不是图像文件卡住或丢失的问题。

我还尝试在 Internet 上搜索以了解 Sprite Kit 纹理文件命名约定的工作原理,但我找不到任何有关该问题的文档。

谁能简要解释一下它是如何工作的,或者至少告诉我一个不涉及重命名我的所有图像文件或为我的所有精灵明确定义大小的解决方案?

谢谢, utr

【问题讨论】:

    标签: ios objective-c retina-display sprite-kit asset-catalog


    【解决方案1】:

    如果您使用资产目录,则无需重命名所有文件。如果您使用 Xcode SpriteKit 模板创建项目,只需单击 Images.xcassets。然后将图像拖放到适当的位置。您也可以通过新建文件 -> 资源 -> 资产目录手动创建资产目录。

    【讨论】:

    • 谢谢,它工作得很好!不过,我仍然不明白 Apple Adventure 应用程序是如何工作的。它仅将资产目录用于应用程序图标和启动图像。
    • 它为地图和角色使用纹理图集。
    • 我也使用纹理图集,但没有帮助。纹理图集上是否有一个选项可以让 Xcode 知道其中的图像是否要用作视网膜分辨率纹理?
    • Adventure 似乎只使用视网膜图像。您应该将视网膜(@2x)图像和正常分辨率图像放在同一个图集中。然后只需使用其基本名称引用 sprite。
    • 这与整个观点背道而驰。我也只使用视网膜图像,所以我不希望每个图像都有正常和视网膜分辨率版本。我想复制 Adventure 应用程序的功能:只有视网膜图像,没有任何后缀,并且仍然通过简单地通过不带扩展名的图像名称引用它们来使用它们。
    【解决方案2】:

    我自己也在寻找答案,看起来冒险游戏示例专门处理视网膜尺寸是这样的:

    // On iPhone/iPod touch we want to see a similar amount of the scene as on iPad.
    // So, we set the size of the scene to be double the size of the view, which is
    // the whole screen, 3.5- or 4- inch. This effectively scales the scene to 50%.
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
       viewSize.height *= 2;
       viewSize.width *= 2;
    }
    

    我很想听听任何人对这段代码的评论,如果它确实与使用仅视网膜图像而不使用 @2x 后缀有关。

    【讨论】:

    • 因为存在 3x 设备,所以使用 [UIScreen mainScreen].scale 作为乘数。