iOS SpriteKit animation does not appear

2019-02-21 00:48发布

问题:

I'm loading an animation using textures from a TextureAtlas.

But the animation does not appear on screen.

I appears only when I NSLog the Textures! Looks like a bug.

Does somebody made similar experience?

SKTextureAtlas *atlas = [SKTextureAtlas atlasWithRetinaCorrection:spriteSheetName_];
if ([atlas.textureNames count] == 0) return;
NSArray *r = [self getSprites:WEAPON_FIREANIMATION ofDict:atlas.textureNames];
if ([r count] == 0)return;


SKSpriteNode *firstSprite = (SKSpriteNode*)[self childNodeWithName:tFIRSTSPRITE];
[firstSprite removeActionForKey:aFIRE_ANIM];

NSMutableArray *walkAnimFrames = [NSMutableArray array];
int k =0;
if (self.weaponAnimDuration == 0)
{
    k = (self.weaponShootInterval / 0.1f)/[r count];
} else
{
    k = (self.weaponAnimDuration / 0.1f)/[r count];
}
for (int i = 0; i<k; i++)
{
    for (NSString *sname in r)
    {
        [walkAnimFrames addObject:[SKTexture textureWithImageNamed:sname]];
    }

}
NSLog(@"%@",walkAnimFrames);

SKAction *weaponAnim = [SKAction animateWithTextures:walkAnimFrames timePerFrame:0.1f];
[firstSprite runAction:weaponAnim withKey:aFIRE_ANIM];

#import "SKTextureAtlas+MySKTextureAtlas.h"
@implementation SKTextureAtlas (MySKTextureAtlas)

+(SKTextureAtlas*)atlasWithRetinaCorrection:(NSString*)name
{
    if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] == YES && [[UIScreen mainScreen] scale] == 2.00)
    {
        name = [NSString stringWithFormat:@"%@@2x",name];
    }

    NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:@"atlasc"];
    if (path == Nil) return Nil;

    return [SKTextureAtlas atlasNamed:name];
}

@implementation NSArray (Tools)


-(NSArray*)animationTextureFrames
{
    NSMutableArray *rr = [NSMutableArray new];
    for (NSString *name in self)
    {
        SKTexture *tex = [SKTexture textureWithImageNamed:name];
        [rr addObject:tex];
    }
    return rr;
}

回答1:

I found the bug!

I had to preload the textures.

 [SKTexture preloadTextures:explosionTextures withCompletionHandler:^(void){}];


回答2:

This is how I do mine, and havent had any issues yet.

    NSMutableArray *textures = [NSMutableArray arrayWithCapacity:5];
    for (int i = 1; i < 5; i++) {
        NSString *textureName = [NSString stringWithFormat:@"rocket%d", i];
        SKTexture *texture = [SKTexture textureWithImageNamed:textureName];
        [textures addObject:texture];
    }

    self.rocketAnimation = [SKAction animateWithTextures:textures timePerFrame:0.1];
    // add animation to my sprite
    [self.projectile runAction:[SKAction repeatActionForever:self.rocketAnimation]];
    // add spite to screen etc...
    [self addChild:self.projectile];


回答3:

See this post, there is a bug when images have a lot of transparent space using texture atlas.

SKTexture returns wrong size?



回答4:

NSLog is very slow compared to most other operations. Just inserting that call adds a significant pause to the main thread of your app. I'm guessing that your texture loading is sending tasks off to the GPU. Without the NSLog call the GPU may not have enough time to complete the tasks. Maybe you can preload the textures.



回答5:

Go to you'r Project and follow these steps:- 1> Go to Build Settings, 2> Search for Enable Texture Atlas Generation and select YES