我开发了一款使用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");}];
}
我走对了路吗?理想情况下,我想在游戏开始前预装所有动画,以便动画顺利运行。
答案 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。因此,如果您在模拟器上进行测试,请在真实设备上进行检查。