问题
When you preload textures using the spritekit preloadTextures function, it loads all the textures in the provided array into the memory at once.
If you don't have the ability to split up your levels in your game with 'loading screens' but do have separate levels with different image files than each other, how can you keep from storing all the images in memory at once without sacrificing frame rate when spritekit loads the images when it needs to?
回答1:
You could create a singleton class with methods for loading and unloading resources specific to the level you are currently playing. For instance, if you have textures a, b, and c that need to be loaded for level one, and textures x, y, and z for level 2, you could have a method -(void)loadLevelOneTextures;
and a -(void)loadLevelTwoTextures;
as well as a -(void)unloadLevelOneTextures;
and -(void)unloadLevelTwoTextures;
This way, you can tell the singleton to load the textures before you need them, and when you're done you tell it to release them.
//GameTextureLoader.h
//
@import SpriteKit;
@import Foundation;
@interface GameTextureLoader : NSObject
@property (strong, nonatomic)NSMutableArray *levelOneTextures;
@property (strong, nonatomic)NSMutableArray *levelTwoTextures;
+ (GameTextureLoader *)sharedTextures;
- (void)loadLevelOneTextures;
- (void)unloadLevelOneTextures;
- (void)loadLevelTwoTextures;
- (void)unloadLevelTwoTextures;
And the implementation:
//GameTextureLoader.m
//
#import "GameTextureLoader.h"
@implementation GameTextureLoader
+ (GameTextureLoader *)sharedTextures{
static dispatch_once_t onceToken;
static id sharedInstance;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
- (instancetype)init{
self = [super init];
if (self)
{
self.levelOneTextures = [[NSMutableArray alloc] init];
self.levelTwoTextures = [[NSMutableArray alloc] init];
return self;
}
else{
exit(1);
}
}
- (void)loadLevelOneTextures{
//Order of images will determin order of textures
NSArray *levelOneImageNames = @[@"imageA", @"imageB", @"imageC"];
for (NSString *image in levelOneImageNames){
SKTexture *texture = [SKTexture textureWithImageNamed:image];
[self.levelOneTextures addObject:texture];
}
}
- (void)loadLevelTwoTextures{
//Order of images will determin order of textures
NSArray *levelTwoImageNames = @[@"imageX", @"imageY", @"imageZ"];
for (NSString *image in levelTwoImageNames){
SKTexture *texture = [SKTexture textureWithImageNamed:image];
[self.levelTwoTextures addObject:texture];
}
}
- (void)unloadLevelOneTextures{
[self.levelOneTextures removeAllObjects];
}
- (void)unloadLevelTwoTextures{
[self.levelTwoTextures removeAllObjects];
}
You would do this for each level you have, and then to access the the textures you would do something like this. (Be sure to first import GameTextureLoader.h)
GameTextureLoader *loader = [GameTextureLoader sharedTextures];
[loader loadLevelOneTextures];
SKSpriteNode *node = [SKSpriteNode spriteNodeWithTexture:loader.levelOneTextures[0]];
[self addChild:node];
来源:https://stackoverflow.com/questions/21868609/sktexture-preloading