SpriteKit SKAction animateWithTextures 在第一次使用 Texture Atlasing 时无法正确渲染。
我有一个场景,它初始化一个精灵并在它上面运行一个动作,当我不使用纹理图集时效果很好。现在的问题是,当场景第一次加载时,它绘制的精灵帧大小与其纹理大小相同,因此精灵被拉伸。我有一个后退按钮,所以当我退出并重新进入场景时,它会正常加载。它不会影响 Texture Atlases 中的任何其他精灵纹理,只会影响动画纹理,奇怪的是它只在第一次渲染时发生。
注意:我使用的是一个单例,它有一个数组存储在 ViewController.m 文件中生成的所有动画。
** 添加 **
好的,我已经做了很多实验,我得出的结论是自动图集生成器解释我的文件名的方式一定有问题,我认为这与“@2x”标签有关特定。
我已经尝试通过删除名称的“.atlas”部分来重命名 atlas 文件夹,并且图像可以完美呈现,当然这不是理想的解决方案,因为这意味着更多的绘图调用。
我命名图像的方式如下...
主题-名称-编号-分辨率-设备-PNG
因此,例如,图像将被称为“SPOOKY_tree_0@2x~iphone.png”
然后我使用辅助方法将它加载到缓存单例中......
- (SKAction *)animationWithFile:(NSString *)name theme:(NSString *)theme frameCount: (int)frameCount delay:(float)delay {
// Load the animation frames as textures and create the sprite frames
NSMutableArray *frames = [NSMutableArray arrayWithCapacity:frameCount];
for (int i = 0; i < frameCount; i++) {
NSString *retina;
if ([GLOBAL _hd]) {
retina = @"@2x";
} else { retina = @""; }
NSString *deviceType;
if ([GLOBAL _ipad]) {
deviceType = @"~ipad";
} else { deviceType = @"~iphone"; }
// Create the file name
NSString *file = [NSString stringWithFormat:@"%@%@_%d%@%@", theme, name, i, retina, deviceType];
// Create the texture/frame
SKTexture *frame = [SKTexture textureWithImageNamed:file];
[frames addObject:frame];
}
// Return the animation object from all the sprite animation frames
return [SKAction animateWithTextures:frames timePerFrame:delay];
}
// Return the animation object from all the sprite animation frames
return [SKAction animateWithTextures:frames timePerFrame:delay];
然后使用“名称”变量将其存储在一个键下的NSMutableDictionary中,就像这样......
- (void)loadPegAnimations {
NSString *newName;
SKAction *newAnimation;
int newFrameCount;
CGFloat fps = 1.0/20.0;
newName = kP1_DEPLOYING_PEG;
newFrameCount = 9;
newAnimation = [self animationWithFile:newName theme:pegTheme frameCount:newFrameCount delay:fps];
[self addAnimation:newAnimation byName:newName];
newName = kP1_LOSING_PEG;
newFrameCount = 22;
newAnimation = [self animationWithFile:newName theme:pegTheme frameCount:newFrameCount delay:fps];
[self addAnimation:newAnimation byName:newName];
newName = kP2_DEPLOYING_PEG;
newFrameCount = 9;
newAnimation = [self animationWithFile:newName theme:pegTheme frameCount:newFrameCount delay:fps];
[self addAnimation:newAnimation byName:newName];
newName = kP2_LOSING_PEG;
newFrameCount = 22;
newAnimation = [self animationWithFile:newName theme:pegTheme frameCount:newFrameCount delay:fps];
[self addAnimation:newAnimation byName:newName];
}
当我想使用该动画时,我使用“[[PEGOGraphicLoader sharedGraphicLoader] frameByName:kP1_DEPLOYING_PEG]];”行调用单例缓存。它返回一个 SKAction *。
我想不知何故,当它为动画调用图像时,它会将@2x 重新应用于图像并尝试将它们压缩到精灵帧中,但我不确定。此外,这仍然不能解释动画在第一次之后正常渲染的事实。
我已经尝试将分辨率元素和设备元素排除在 -textureWithImageNamed: 方法之外,但是纹理图集根本没有找到图像,只是显示为巨大的 X。我想我会在没有启用纹理图集的情况下工作,直到我知道它绝对不是纹理图集生成器的错误。
与此同时,我正在考虑使用 hack 类型命名约定,这样我就可以根据设备类型等以编程方式决定要加载哪些纹理,并且每种设备类型都有不同的 atlas 文件夹。
如果有人遇到过类似的问题或想告诉我我做错了什么,那么我想知道。我还没有在实际设备上测试游戏,所以可能是模拟器的问题。