gpt4 book ai didi

ios - SpriteKit SKTextureAtlas,在加载纹理时由于内存压力而终止

转载 作者:行者123 更新时间:2023-12-01 19:02:47 24 4
gpt4 key购买 nike

类似于 WWDC 的 SpriteKit 特色游戏“冒险”,我尝试通过图 block 加载我的背景图像。我创建了一个纹理图集,其中包含 6,300 个“图 block ”,每个“图 block ”大小为 100x100 像素。完整的背景图像总共为 30,000x2048(用于视网膜显示器)。这个想法是背景将从右向左移动(横向滚动条)。第一列和最后一列匹配,因此它们看起来是连续的。

当应用程序运行时,它会加载我的初始加载屏幕和标题图像,并在我的内存选项卡中加载到 54MB ,CPU 使用率为 16% 。在我选择我的关卡之前,这与我在菜单中导航时保持不变,这会告诉后台线程加载关卡 Assets (其中包含上述背景图像)。整个 .atlas 文件夹显示仅为 35.4MB 。我不认为这是一个问题,因为 Adventure .atlas 文件夹(来自 WWDC)显示仅为 32.7MB

一旦我选择了关卡,它会在我开始收到内存警告之前在 .atlas 文件夹中加载大约 20 个纹理并且它会导致应用程序崩溃。我检查了 Instruments 是否有泄漏,它没有显示任何内存泄漏。我没有收到任何编译器错误(甚至没有 EXC_BAD_ACCESS 错误)。我查看了我的设备控制台,发现了应用程序崩溃的几行代码,但它看起来对我没有多大意义。我也检查了僵尸,但似乎没有找到。

CoreLevel.m

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
// Used to determine time spent to load
NSDate *startDate = [NSDate date];

// Atlas to load
SKTextureAtlas *tileAtlas = [SKTextureAtlas atlasNamed:@"Day"];

// Make sure the array is empty, before storing the tiles
sBackgroundTiles = nil;
sBackgroundTiles = [[NSMutableArray alloc] initWithCapacity:6300];

// For each row (21 Totals Rows)
for (int y = 0; y < 21; y++) {

// For each Column (100 Total Columns)
for (int x = 1; x <= 100; x++) {

// Get the tile number (0 * 32) + 0;
int tileNumber = (y * 300) + x;

// Create a SpriteNode of that tile
SKSpriteNode *tileNode = [SKSpriteNode spriteNodeWithTexture:[tileAtlas textureNamed:[NSString stringWithFormat:@"tile_%d.png", tileNumber]]];

// Position the SpriteNode
CGPoint position = CGPointMake((x * 100), (y * 100));
tileNode.position = position;

// At layer
tileNode.zPosition = -1.0f;
tileNode.blendMode = SKBlendModeReplace;

// Add to array
[(NSMutableArray *)sBackgroundTiles addObject:tileNode];
}
}
NSLog(@"Loaded all world tiles in %f seconds", [[NSDate date] timeIntervalSinceDate:startDate]);
});

这似乎与调试控制台的崩溃有关:
com.apple.debugserver-300.2[9438] <Warning>: 1 +0.000000 sec [24de/1807]: error: ::read ( -1, 0x4069ec, 18446744069414585344 ) => -1 err = Bad file descriptor (0x00000009)
com.apple.debugserver-300.2[9438] <Warning>: Exiting.
com.apple.launchd[1] (UIKitApplication:tv.thebasement.Coin-Voyage[0x641d][9441]) <Notice>: (UIKitApplication:tv.thebasement.Coin-Voyage[0x641d]) Exited: Killed: 9

我没有足够的声誉来发布图片,所以这里是我在 Instruments 中分配的屏幕截图的链接:

http://postimg.org/image/j17xl39et/

非常感谢任何帮助和建议!如果我遗漏了一些相关信息,我很高兴更新。

最佳答案

图像文件(PNG、JPG、atlas 文件夹等)的文件大小不会告诉您内存使用情况。

相反,您必须使用以下公式计算纹理内存使用情况:

width * height * (color bit depth / 8) = texture size in bytes

例如,尺寸为 4096x4096 像素和 32 位颜色深度(4 字节)的图像在作为纹理加载(未压缩)时使用这么多内存:
4096 * 4096 * 4 = 67108864 bytes (64 Megabytes)

根据您的规范(6,300 个图 block ,每个 100x100 像素,假设它们都是唯一的),您的方式,远远超过纹理内存使用的任何合理限制(约 1.5 GB!)。考虑到 35 兆字节的图集大小(对于图集顺便说一句,它是 巨大的 )并假设压缩比仅为 10:1,您可能仍在查看 350+ 兆字节的纹理内存使用量。

关于ios - SpriteKit SKTextureAtlas,在加载纹理时由于内存压力而终止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21764738/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com