动画首次加载时会滞后

时间:2015-01-20 22:44:12

标签: ios objective-c animation sprite-kit

我开发了一款使用Sprite Kit的iOS游戏,其中包含许多我动画的敌人和障碍物。每次动画帧第一次加载时,游戏都会稍微滞后,然后运行正常。

例如,我的一个敌人看起来像这样:

Fox实施文件:

- (id)initWithTexture:(SKTexture *)nodetexture
{
    self = [super initWithTexture:nodetexture];
    if (self) {
        //Initialization code
        [self setScale:0.2];
        [self setSpeed:20];
        self.physicsBody.allowsRotation = false;
        self.physicsBody.contactTestBitMask = 0x1 << 1 | 0x1 << 3;
        self.physicsBody.categoryBitMask = 0x1 << 2;//enemy
        self.physicsBody.collisionBitMask = 0x1 << 1 | 0x1 << 3;
        [self animateSelf];
    }
    return self;
}

- (void) animateSelf{
    [super animateSelf];
    NSMutableArray *textures = [NSMutableArray arrayWithCapacity:16];
    for (int i = 1; i < 5; i++) {
        NSString *textureName = [NSString stringWithFormat:@"fox%d.png", i];
        SKTexture *texture =[SKTexture textureWithImageNamed:textureName];
        [textures addObject:texture];
    }
    [self removeActionForKey:[NSString stringWithFormat:@"animate %@", self.class]];
    [self runAction:[SKAction sequence:@[[SKAction repeatAction:[SKAction sequence:@[[SKAction runBlock:^{
        self.xScale = -0.2;
        [self jumpEntity];
        [self setSpeed:40];
        [self impulseEntityRight];
        [self setSpeed:20];
        self.runAnimation = [SKAction animateWithTextures:textures timePerFrame:3];
    }], [SKAction waitForDuration:20], [SKAction runBlock:^{
        self.xScale = 0.2;
        [self jumpEntity];
        [self setSpeed:40];
        [self impulseEntityLeft];
        [self setSpeed:20];
        [self runAction:[SKAction repeatActionForever:self.runAnimation]];
    }], [SKAction waitForDuration:20]]] count:5]]] withKey:[NSString stringWithFormat:@"animate %@", self.class]];
}

帧存储在.atlas文件中,我相信滞后的原因是第一次运行for循环,但这只是一个假设。

我尝试在GameViewController中按照这些行预加载帧:

GameViewController实现文件:

- (void)viewDidLoad
{
    [super viewDidLoad];
    //Load new game
    [self initialiseGameScene];
    [self.gamescene.physicsWorld setContactDelegate:self];
    [self checkTiltBool];
    self.gamestarted = false;
    self.startedbytilt = false;
    [self addListenersToButtons];
    [self instantiateGestureRecognizers];
    self.spawnedobjects = [[NSMutableArray alloc] init];
    if (self.tiltbool == true){
        [self startGame];
    }
    [self updateLifeIcons];
    NSMutableArray *frames = [[NSMutableArray alloc]init];
    for (int i=0; i<[SKTextureAtlas atlasNamed:@"fox"].textureNames.count; i++) {
        [frames addObject:[SKTexture textureWithImageNamed:[SKTextureAtlas atlasNamed:@"fox"].textureNames[i]]];
    }
    [SKTexture preloadTextures:frames withCompletionHandler:^{NSLog(@"Complete");}];

}

我走对了路吗?理想情况下,我想在游戏开始前预装所有动画,以便动画顺利运行。

1 个答案:

答案 0 :(得分:0)

我强烈建议您只初始化纹理数组一次。目前,每次调用animateSelf方法时都会创建一个新的NSMutableArray。

所以请看这部分:

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

并将其放在一个方法中,该方法将在application-start中调用。例如,您可以创建一个可以从代码中访问的全局变量。

如果您使用它,还有一个问题可能是iOS模拟器。我经常遇到的问题是我在iOS模拟器上运行了一个游戏而且它是滞后的并且表现不佳(大约23FPS)。但在真正的设备上它可以正常使用60FPS。因此,如果您在模拟器上进行测试,请在真实设备上进行检查。