I developed an iOS game using Sprite Kit with a lot of enemies and obstacles which I animated. Every time the animation frames are loaded for the first time, the game lags a little and then it runs fine.
For example my one of the enemies looks like this:
Fox implementation file:
- (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]];
}
The frames are stored in an .atlas file and I believe the reason for the lag is running the for loop for the first time but that is just an assumption.
I tried preloading the frames in the GameViewController along those lines:
GameViewController Implementation File :
- (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");}];
}
Am I going the right way? Ideally, I would like to preload all the animations before the game starts so the animations run smoothly.