1

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 文件夹。

如果有人遇到过类似的问题或想告诉我我做错了什么,那么我想知道。我还没有在实际设备上测试游戏,所以可能是模拟器的问题。

4

2 回答 2

2

我发现自己在使用 TextureAtlas 时遇到了同样的问题。我尝试了不同的设置,发现设置Resize: YESRestore: YES Boolean 选项纠正了我错误大小的精灵动画。希望这可以帮助

于 2013-11-11T15:00:18.067 回答
1

我以为 SpriteKit 会自动处理 Retina。尝试删除更改字符串@2x 的代码行,还尝试删除设备类型,看看是否也没有为您处理。

我还注意到,如果您使用 animateWithTextures 设置 resize:NO 和 restore:NO 会有所帮助

于 2013-10-06T01:25:01.527 回答