我正在开发一款iOS游戏,可以生成大块的2d磁贴,用户可以“无限地”移动。
仅供上下文使用:每个磁贴为32x32px,每个“块”包含4x4个磁贴(总共16个)。大多数磁贴都是空的,但是当某些东西被放置在磁贴上时,如果用户移动太远并且该块“卸载” - 我将块和磁贴数据保存到磁盘。
现在,块和磁贴都使用NSCoding
协议。块可以保存NSArray
个图块和一些布尔值,每个图块可以保存几个数字/布尔值。
这很有效 - 当块卸载它时会保存,当块再次加载时,它会被恢复。
但是,我注意到写入磁盘方法非常简短地杀死了我的FPS。因为当玩家移动时通常会有几个块被卸载在一起,并且当它们被卸载时,玩家已经移动得越来越多并且卸载 - 它会加起来。
我已经尽力确保只保存实际更改的块,并且我最好组织保存代码以避免在每次保存调用时实例化对象。
有没有更好的方法可以在不影响FPS的情况下保存数据?
这是Chunk保存代码:
-(void)saveToDisk {
if( !self.hasUnsavedChanges ){
NSLog(@"skipping saving chunk that has not changed");
return;
}
[self.saveFile writeData:self withKey:self.savefileKey];
self.hasUnsavedChanges = false;
}
-(void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeObject:[NSNumber numberWithFloat:self.position.x] forKey:@"chunk.x"];
[encoder encodeObject:[NSNumber numberWithFloat:self.position.y] forKey:@"chunk.y"];
[encoder encodeObject:tiles forKey:@"chunk.tiles"];
}
-(id)initWithCoder:(NSCoder *)decoder {
Chunk *restore = [self init];
NSNumber *xChunkNum = [decoder decodeObjectForKey:@"chunk.x"];
NSNumber *yChunkNum = [decoder decodeObjectForKey:@"chunk.y"];
restore.position = [Coord coordWithX:[xChunkNum intValue] Y:[yChunkNum intValue]];
tiles = [decoder decodeObjectForKey:@"chunk.tiles"];
return restore;
}
瓷砖代码:
-(void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeObject:[NSNumber numberWithFloat:self.worldContextCoordinate.x] forKey:@"tile.world.x"];
[encoder encodeObject:[NSNumber numberWithFloat:self.worldContextCoordinate.y] forKey:@"tile.world.y"];
[encoder encodeObject:[NSNumber numberWithFloat:self.color.red] forKey:@"tile.color.red"];
[encoder encodeObject:[NSNumber numberWithFloat:self.color.green] forKey:@"tile.color.green"];
[encoder encodeObject:[NSNumber numberWithFloat:self.color.blue] forKey:@"tile.color.blue"];
[encoder encodeObject:[NSNumber numberWithFloat:self.isSourceTile] forKey:@"tile.isSource"];forKey:@"tile.hasBlackNeighbor"];
}
-(id)initWithCoder:(NSCoder *)decoder {
Tile *restore = [self init];
NSNumber *xNum = [decoder decodeObjectForKey:@"tile.world.x"];
NSNumber *yNum = [decoder decodeObjectForKey:@"tile.world.y"];
[restore setWorldContextCoordinate:b2Vec2( [xNum floatValue], [yNum floatValue] )];
NSNumber *red = [decoder decodeObjectForKey:@"tile.color.red"];
NSNumber *green = [decoder decodeObjectForKey:@"tile.color.green"];
NSNumber *blue = [decoder decodeObjectForKey:@"tile.color.blue"];
restore.color = [CCColor colorWithRed:[red floatValue] green:[green floatValue] blue:[blue floatValue]];
restore.isSourceTile = [decoder decodeObjectForKey:@"tile.isSource"];
return restore;
}
答案 0 :(得分:0)
鉴于您不需要担心影响UI或UX的完成事件,您应该能够异步运行这些事件。如果需要,您可以使用完成块执行此操作,以便您可以在必要时处理完成事件。
- (void)saveToDiskAsyncWithCompletion:(void(^)(BOOL finished))completion
{
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, NO), ^{
[self saveToDisk];
// or you could run any of your other operations here too.
dispatch_async(dispatch_get_main_queue(), ^(void){
completion(YES);
});
});
}