大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处.

如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;)


用plist列表文件来表示游戏数据

因为在这个炸弹人游戏中有很多不同的关卡,难度依次上升,所以对于每个关卡的数据我们必须存放在某个地方,有很多种保存方法,这里我们选择使用plist列表文件来保存每个关卡的数据.

选择Resources目录,在其中新建一个plist文件,命名为LevelsData.plist.

下面我们要想一想里面到底要存放神马数据.

大致有这些每一关卡砖块的数量,每关敌人的数量,每关剩余的时间限制和过关奖励的分数.

其中关卡敌人的数量需要在细化下,因为我们在游戏开始的一个目标就是建立多种敌人,所以这里要按每种敌人给出一个对应的数量.

按照上述所讨论的内容,最终建立的plist内容大致是如下这个样子:

游戏数据的内存表示

有了plist文件还不够,我们还需要将plist的内容读取到内存中去,这是以类实例的方式来读取的.

我们在Xcode中新建一个GameData类,继承于NSObject.

打开GameData.h头文件,设置如下:

#import <Foundation/Foundation.h>
//管理游戏数据的类
@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 ;)

(NO.00005)iOS实现炸弹人游戏(七):游戏数据的序列化表示的更多相关文章

  1. (NO.00005)iOS实现炸弹人游戏(八):游戏主角(一)

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 最近一直在做另一个RPG游戏,所以本系列迟迟没有更新,上一篇博 ...

  2. (NO.00005)iOS实现炸弹人游戏(三):从主场景类谈起

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 我又粗粗看了下整个项目的代码,比较多: 不少类都与其他类有着千丝 ...

  3. (NO.00005)iOS实现炸弹人游戏(十一):怪物之火精灵

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 从本篇开始我们一次介绍一下游戏中敌人的制作过程.看过第一篇的小 ...

  4. (NO.00005)iOS实现炸弹人游戏(五):游戏数据的初始化(二)

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 我们现在来依次看一下上篇中提到的各个方法,首先介绍的是updat ...

  5. (NO.00005)iOS实现炸弹人游戏(四):游戏数据的初始化(一)

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 上一篇我们初步看了一下MainScene类的初始化方法里都做了神 ...

  6. (NO.00005)iOS实现炸弹人游戏(二):素材选择的取舍

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 前面一篇里我们基本明确了游戏的大致玩法和特点.下面就游戏中会用到 ...

  7. (NO.00005)iOS实现炸弹人游戏(一):游戏的整体规划设计

    在这新的系列中,我们来尝试完成一款经典的游戏:炸弹人 这是以前红白机上的炸弹人,由于游戏可玩性强,玩法又简单,在后面的机型上陆续推出了很多款续作. 在随后的触屏设备上也出现了炸弹人的模拟版,用的是模拟 ...

  8. (NO.00005)iOS实现炸弹人游戏(十):游戏主角(三)

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 下面我们来看游戏主角类里面几个播放特殊动画的方法,首先从run ...

  9. (NO.00005)iOS实现炸弹人游戏(九):游戏主角(二)

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 上篇介绍了游戏主角的初始化方法,下面我们一次来实现主角的其他方 ...

随机推荐

  1. Codeforces Round#402(Div.1)掉分记+题解

    哎,今天第一次打div1 感觉头脑很不清醒... 看到第一题就蒙了,想了好久,怎么乱dp,倒过来插之类的...突然发现不就是一道sb二分吗.....sb二分看了二十分钟........ 然后第二题看了 ...

  2. Android自定义模糊匹配搜索控件(二)

    在项目中遇到一个需要通过某个字的值筛选匹配带出其他信息的需求,在这里将实现思路整理出来. 源码地址:https://github.com/whieenz/SearchSelect 先看效果图 上图中的 ...

  3. 计科1702冯亚杰C语言程序设计预备作业

    阅读邹欣老师的博客--师生关系,针对文中的几种师生关系谈谈你的看法,你期望的师生关系是什么样的? 答:首先老师和学生之间要互相尊重,我认为这是必要的.在第一点的基础上师生要互相帮助,互相配合,共同进步 ...

  4. ⏰Day.js 2kB超轻量时间库 和Moment.js一样的API

    Moment.js 是一个大而全的 JS 时间库,很大地方便了我们处理日期和时间.但是 Moment.js太重了(200k+ with locals),可能一般项目也只使用到了她几个常用的API.虽然 ...

  5. 360面试-C++后端(实习)

    在线远程视频面试 一面: 自我介绍. 知道哪几种排序算法,各算法的时间复杂度. 解决hash冲突的几种方式. 有哪些方法清除cache中旧的数据.不太清楚,我扯到了操作系统中缺页中断的页面置换原理上, ...

  6. SQL之排序

    1.按多个列排序 经常需要按不止一个列进行数据排序.例如,如果要显示雇员名单,可能希望按姓和名排序(首先按姓排序,然后在每个姓中再按名排序).如果多个雇员有相同的姓,这样做很有用. 要按多个列排序,简 ...

  7. sqlserver批量更新数据

    update t_hr_teadept set rjkm=b.yjkmfrom t_hr_teadept a inner join t_tr_bzxx_km b on a.bzh=b.bzh wher ...

  8. filter和listener的生命周期

    filter(过滤器)和listener(监听器)的生命周期 老实说 生命周期要是说成作用的时间范围我会理解的更好 filter package com.javaweb.filter; import ...

  9. javascript装饰器模式

    装饰器模式 什么是装饰器 原名decorator 被翻译为装饰器 可以理解为装饰 修饰 包装等意 现实中的作用 一间房子通过装饰可以变得更华丽,功能更多 类似一部手机可以单独使用 但是很多人都愿意家个 ...

  10. DuKBitmapImages 图片压缩处理技术

    Android图片压缩上传系列 *压缩中的问题: --图片压缩上如果存在问题,势必造成消耗大量的流量,下载图片的速度慢等影响产品性能,那么如何解决?请看下面: 压缩图片一共多少张?一起压缩?分开压缩? ...