大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;)
用plist列表文件来表示游戏数据因为在这个炸弹人游戏中有很多不同的关卡,难度依次上升,所以对于每个关卡的数据我们必须存放在某个地方,有很多种保存方法,这里我们选择使用plist列表文件来保存每个关卡的数据.
选择Resources目录,在其中新建一个plist文件,命名为LevelsData.plist.
下面我们要想一想里面到底要存放神马数据.
大致有这些每一关卡砖块的数量,每关敌人的数量,每关剩余的时间限制和过关奖励的分数.
其中关卡敌人的数量需要在细化下,因为我们在游戏开始的一个目标就是建立多种敌人,所以这里要按每种敌人给出一个对应的数量.
按照上述所讨论的内容,最终建立的plist内容大致是如下这个样子:
有了plist文件还不够,我们还需要将plist的内容读取到内存中去,这是以类实例的方式来读取的.
我们在Xcode中新建一个GameData类,继承于NSObject.
打开GameData.h头文件,设置如下:
#import //管理游戏数据的类 @interface GameData : NSObject +(id)sharedInstance; @property (nonatomic,assign) NSInteger bombExplodeRange; //炸弹爆炸范围 @property (nonatomic,assign) BOOL isManualExplode; //是否手动引爆 @property (nonatomic,assign) BOOL isFearBomb; //玩家是否怕炸弹 @property (nonatomic,assign) NSInteger bombCountLimit; //炸弹的数量限制 @property (nonatomic,assign) NSInteger life; //玩家的命数 @property (nonatomic,assign) BOOL isPlayerSpeedUp; //玩家是否处于加速状态 @property (nonatomic,assign) BOOL canPlayerAcrossBrick; //玩家是否可以穿砖 @property (nonatomic,assign) BOOL canPlayerAcorssBomb; //玩家是否可以穿炸弹 @property (nonatomic,assign) NSInteger playerTotalScore; //玩家总得分 @property (nonatomic,assign) NSInteger curLevelNumber; //当前关卡序号 @property (nonatomic,assign) NSInteger curLevelBrickCount; //当前关卡砖块数量 //@property (nonatomic,assign) NSInteger curLevelEnemyCount; //当前关卡敌人数量 @property (nonatomic,assign) NSInteger curLevelFSCount; //当前关卡普通敌人的数量 @property (nonatomic,assign) NSInteger curLevelFSGhostCount; //当前关卡FSGhost敌人的数量 @property (nonatomic,assign) NSInteger curLevelFSDogCount; //当前关卡FSDog敌人的数量 @property (nonatomic,assign) NSInteger curLevelFSCatTracerCount; //当前关卡FSCatTracer敌人的数量 @property (nonatomic,assign) NSInteger curLevelGPCount; //当前关卡游戏道具数量 @property (nonatomic,assign) NSInteger curLevelLeftTime; //当前关卡时间限制(秒) @property (nonatomic,assign) NSInteger curLevelPassScore; //当前关卡过关得分 -(void)synchronize; -(void)saveGameData; -(void)loadGameData; -(void)initGameData; -(void)setGameDataWhenLevelLose; //注册默认游戏数据,如果App第一次运行则使用该数据.(因为你还未存入数据) -(void)regDefaultGameData; @end
里面定义了若干属性,分为两部分内容:和当前关卡相关的以及和游戏主角状态相关的内容,大家从属性的名称中大致可以区分出来,这里就不一一介绍了,注释都做的很详细.
GameData类中定义的方法并不多,一个类方法sharedInstance用来返回类的唯一实例,剩下的都是实例方法用来读取和保存游戏数据.
GameData类的实现接下来我们来看一下GameData的实现代码,首先是类单例方法的实现:
//返回GameDate类唯一单例 +(instancetype)sharedInstance{ static dispatch_once_t once; static GameData *sharedInstance; dispatch_once(&once,^{ sharedInstance = [self new]; }); return sharedInstance; }
内容没啥好说的,然后是另一个简单的同步方法:
//将NSUserDefaults数据写入磁盘 -(void)synchronize{ [[NSUserDefaults standardUserDefaults]synchronize]; }
下面是读取数据的loadGameData方法:
//从磁盘上将游戏数据读取出来 -(void)loadGameData{ NSDictionary *dict = [[NSUserDefaults standardUserDefaults] objectForKey:kPlayerData]; self.bombExplodeRange = [dict[kBombExplodeRange] intValue]; self.isManualExplode = [dict[kIsManualExplode] boolValue]; self.isFearBomb = [dict[kIsFearBomb] boolValue]; self.bombCountLimit = [dict[kBombCountLimit] intValue]; self.life = [dict[kLife] intValue]; self.isPlayerSpeedUp = [dict[kIsPlayerSpeedUp] boolValue]; self.canPlayerAcrossBrick = [dict[kCanPlayerAcrossBrick] boolValue]; self.canPlayerAcorssBomb = [dict[kCanPlayerAcrossBomb] boolValue]; self.playerTotalScore = [dict[kPlayerTotalScore] intValue]; self.curLevelNumber = [dict[kCurLevelNumber] intValue]; //取得关卡数据文件的全路径 NSString *plistFullPath = [[NSBundle mainBundle] pathForResource:s_LevelsDataFile ofType:@"plist"]; //读取关卡数据到数组中 NSArray *levelsDataAry = [NSArray arrayWithContentsOfFile:plistFullPath]; NSAssert(self.curLevelNumber > 0 && self.curLevelNumber <= levelsDataAry.count, @"Error curLevel Number!"); //关卡是从1开头,所以要调整为数组中的从0开头. NSInteger index = self.curLevelNumber - 1; //依次取得关卡中的每个数据 self.curLevelBrickCount = [levelsDataAry[index][kCurLevelBrickCount] intValue]; [self initCurLevelEmenyCount:levelsDataAry[index][kCurLevelEnemyCount]]; self.curLevelGPCount = [levelsDataAry[index][kCurLevelGPCount] intValue]; self.curLevelLeftTime = [levelsDataAry[index][kCurLevelLeftTime] intValue]; self.curLevelPassScore = [levelsDataAry[index][kCurLevelPassScore] intValue]; }
代码很简单,就是依次分别读取level和player的数据然后设置对应的实例变量.
最后是写入数据的saveGameData方法:
//将游戏数据写入磁盘 -(void)saveGameData{ //创建数据字典 NSDictionary *dict = @{kBombExplodeRange:@(self.bombExplodeRange), kIsManualExplode:@(self.isManualExplode), kIsFearBomb:@(self.isFearBomb), kBombCountLimit:@(self.bombCountLimit), kLife:@(self.life), kIsPlayerSpeedUp:@(self.isPlayerSpeedUp), kCanPlayerAcrossBrick:@(self.canPlayerAcrossBrick), kCanPlayerAcrossBomb:@(self.canPlayerAcorssBomb), kPlayerTotalScore:@(self.playerTotalScore), kCurLevelNumber:@(self.curLevelNumber) }; //将数据字典写入NSUserDefaults实例 [[NSUserDefaults standardUserDefaults] setObject:dict forKey:kPlayerData]; [self synchronize]; }
该方法是读取方法的逆方法,最后调用了[self synchronize]来将内存中的数据刷入plist中,确保数据不会丢失.
游戏数据类是每个游戏都必不可少的功能类,可以考虑将其做成一个模板类来供不同程序的使用.
下一篇我们继续介绍游戏的其它部分,see you ;)