【iOS-Cocos2d游戏开发之十九】游戏数据存储的四种常

 李华明Himi 原创,转载务必在明显处注明:
转载自【黑米GameDev街区】 原文链接: http://www.himigame.com/iphone-cocos2d/513.html

OK,今天Himi介绍游戏存储这一块,在Android游戏开发中Himi介绍了好几种保存的方式和形式,那么在iOS中也有几种方式,一般常用的有以下四种形式:

1.NSKeyedArchiver(加密形式)

2.NSUserDefaults

  1.  Write写入方式

4.SQLite3

这里Himi就不再介绍SQlite数据库了,Android游戏存储中我也介绍过SQLite如何保存数据,但是由于这一块很多童鞋没有接触过数据库相关知识,所以即使讲了也没作用,那么对于数据数据库的童鞋们可以参考其他博文或书籍进行学习;

首先介绍第一种保存方式:NSKeyedArchiver

代码很简单就不多解释了直接上代码: 

 //=================NSKeyedArchiver========================   
 NSString *saveStr1 = @"我是";  
 NSString *saveStr2 = @"数据";  
 NSArray *array = [NSArray arrayWithObjects:saveStr1, saveStr2, nil];   
 //----Save  
 //这一句是将路径和文件名合成文件完整路径  
 NSString *Path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];   
 NSString *filename = [Path stringByAppendingPathComponent:@"saveDatatest"];  
 [NSKeyedArchiver archiveRootObject:array toFile:filename];  
 //用于测试是否已经保存了数据  
 saveStr1 = @"hhhhhhiiii";  
 saveStr2 =@"mmmmmmiiii";   
 //----Load  
 array = [NSKeyedUnarchiver unarchiveObjectWithFile: filename];  
 saveStr1 = [array objectAtIndex:0];  
 saveStr2 = [array objectAtIndex:1];   
 CCLOG(@"str:%@",saveStr1);  
 CCLOG(@"astr:%@",saveStr2);  

首先介绍第二种保存方式:NSUserDefaults

代码很简单就不多解释了直接上代码:

 //=================NSUserDefaults========================  
 NSString *saveStr1 = @"我是";  
 NSString *saveStr2 = @"数据";  
 NSArray *array = [NSArray arrayWithObjects:saveStr1, saveStr2, nil];           
 //Save  
 NSUserDefaults *saveDefaults = [NSUserDefaults standardUserDefaults];  
 [saveDefaults setObject:array forKey:@"SaveKey"];  
 //用于测试是否已经保存了数据  
 saveStr1 = @"hhhhhhiiii";  
 saveStr2 =@"mmmmmmiiii";    
 //---Load  
 array = [saveDefaults objectForKey:@"SaveKey"];  
 saveStr1 = [array objectAtIndex:0];  
 saveStr2 = [array objectAtIndex:1];  
 CCLOG(@"str:%@",saveStr1);  
 CCLOG(@"astr:%@",saveStr2);  

首先介绍第三种保存方式:Write写入方式

代码很简单就不多解释了直接上代码:

 //=================Write写入方式========================  
 NSString *saveStr1 = @"我是";  
 NSString *saveStr2 = @"数据";  
 NSArray *array = [NSArray arrayWithObjects:saveStr1, saveStr2, nil];   
 //----Save  
 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);  
 NSString *documentsDirectory = [paths objectAtIndex:0];  
 if (!documentsDirectory) {  
     NSLog(@"没找到");  
 }  
 NSMutableArray *saveDataArray=nil;  
 NSString *appFile = [documentsDirectory stringByAppendingPathComponent:@"Savedatas.plist"];  
 [[NSArray arrayWithObjects:array,nil] writeToFile:appFile atomically:NO];  
 //用于测试是否已经保存了数据  
 saveStr1 = @"hhhhhhiiii";  
 saveStr2 =@"mmmmmmiiii";    
 //----Load  
 if([[NSFileManager defaultManager] fileExistsAtPath:appFile]){  
     saveDataArray = [NSMutableArray arrayWithContentsOfFile:appFile];      
 } else{  
     saveDataArray = [NSMutableArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Savedatas" ofType:@"plist"]];  
 }  
 NSArray *strArray = [saveDataArray objectAtIndex:0];   
 saveStr1 = [strArray objectAtIndex:0];  
 saveStr2 = [strArray objectAtIndex:1];  
 CCLOG(@"str:%@",saveStr1);  
 CCLOG(@"astr:%@",saveStr2);   

不论哪种形式代码都很容易理解,那么以上三种保存方式代码中都带有如下两行代码;

 saveStr1 = @"hhhhhhiiii";  
 saveStr2 =@"mmmmmmiiii";   

我已经注释上了,为了验证是否保存数据成功,如果没有保存成功,最后打印的肯定就是hhhhhhiiiiiiiii,mmmmiiiii啦~正常保存的话如下图控制台信息:

由于本章介绍过于简单,那么下面Himi对Write写入方式保存数据和读取数据封装了两个方法这里放出,给童鞋们行个方便:(其他两种大家封装起来风容易了,这里就不写了);

封装的函数如下:

 //保存游戏数据  
 //参数介绍:  
 //   (NSMutableArray *)data :保存的数据  
 //   (NSString *)fileName :存储的文件名  
 -(BOOL) saveGameData:(NSMutableArray *)data  saveFileName:(NSString *)fileName  
 {  
     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);  
     NSString *documentsDirectory = [paths objectAtIndex:0];  
     if (!documentsDirectory) {  
         NSLog(@"Documents directory not found!");  
         return NO;  
     }  
     NSString *appFile = [documentsDirectory stringByAppendingPathComponent:fileName];  
     return ([data writeToFile:appFile atomically:YES]);  
 }  
 //读取游戏数据  
 //参数介绍:  
 //   (NSString *)fileName :需要读取数据的文件名  
 -(id) loadGameData:(NSString *)fileName  
 {  
     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);  
     NSString *documentsDirectory = [paths objectAtIndex:0];  
     NSString *appFile = [documentsDirectory stringByAppendingPathComponent:fileName];  
     NSMutableArray *myData = [[[NSMutableArray alloc] initWithContentsOfFile:appFile] autorelease];  
     return myData;  
 }  

使用代码如下:

 NSString *saveStr1 = @"测试保存读取";  
 NSString *saveStr2 = @"两个函数";  
 NSMutableArray *array = [NSMutableArray arrayWithObjects:saveStr1, saveStr2, nil];   
 [self saveGameData:array saveFileName:@"Himi"];  
 NSMutableArray*temp =(NSMutableArray*)[self loadGameData:@"Himi"];  
 CCLOG(@"%@--%@",[temp objectAtIndex:0],[temp objectAtIndex:1]);

运行效果截图如下:

这里Himi要提醒大家两点细节也是需要注意的地方:

1.对于取出数据的时候需要注意,例如如下代码:

 NSUserDefaults *saveDefaults = [NSUserDefaults standardUserDefaults];   
 NSMutableArray *arraySaveData =[saveDefaults objectForKey:@"OhSaveData"];  
 //NSMutableArray *arraySaveData=[NSMutableArray arrayWithArray:[saveDefaults objectForKey:@"OhSaveData"]];  

第二句代码是通过一个文件名获取你存储的数据,返回数据数组,但是!一定要注意这里返回的数据数组是不可修改的!及时你将读取的数据赋给一个可修改的数组中也一样无法修改其中的数据,所以如果你想将取出的数据进行修改那么这里需要要使用第三行代码来获取,这里Himi将获取出的数据数组首先copy给了可修改数组中,那么此时你的可修改数组就可以正常修改了!

2.修改已经的存储文件;代码如下:

 NSUserDefaults *saveDefaults = [NSUserDefaults standardUserDefaults];   
 [saveDefaults setObject:arraySaveData forKey:@"已经存在的文件名"];  

arraySaveData:表示新的数据数组

OK,本篇就介绍这里吧~继续忙了~

文章导航