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

如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;)


在RPG游戏项目的GameSpace类中原来有一个方法:

-(instancetype)initWithGameScene:(GameScene *)gameScene mapName:(NSString*)mapName;

功能主要为用指定的地图初始化游戏空间布局,后来由于使用方便的原因,增加了一个类似的方法:

-(instancetype)initWithGameScene:(GameScene *)gameScene mapName:(NSString *)mapName
                  spawnAtTilePos:(CGPoint)tilePoint;

该方法比原来的方法仅仅多了一个参数,用来初始化player出现在地图场景中的瓦块位置.

这样就出现了功能类似的2个方法,这势必造成代码的重复,会对将来的代码修改带来非常坏的影响,所以今天我们就想办法对其重构.

首先我们将第一个方法前面的几行代码提炼出去,形成一个新的方法:

-(void)instancePreInit:(GameScene*)gameScene mapName:(NSString*)mapName{
    _viewSize = [CCDirector sharedDirector].viewSize;

    _gameScene = gameScene;
    _tiledMap = [CCTiledMap tiledMapWithFile:mapName];

    _tiledMap.anchorPoint = ccp(0, 0);
    [self addChild:_tiledMap];

    _mh = [[MapHelper alloc]initWithGameScene:gameScene andTiledMap:_tiledMap];

    CCTiledMapLayer *barrierLayer = [_tiledMap layerNamed:@"BarrierLayer"];
    barrierLayer.visible = NO;

    _objGroup = [_tiledMap objectGroupNamed:@"Objects"];

    _gd = [GameData sharedInstance];

    _bgLayer = [_tiledMap layerNamed:@"BGLayer"];
    NSAssert(_bgLayer, @"ERR:地图中没有_bgLayer层!!!");
}

然后在2个方法中分别用该方法替换原有的代码:

-(instancetype)initWithGameScene:(GameScene *)gameScene mapName:(NSString *)mapName
                  spawnAtTilePos:(CGPoint)tilePoint{
    self = [super init];
    if (self) {
        //原功能代码
        [self instancePreInit:gameScene mapName:mapName];
        //其他代码

另一个方法也类似,现在我们来处理后面的代码.

现在创建后续初始化方法,把以上两个方法的后半段代码抽取到其中:

-(void)instanceSufInit:(CGPoint)spawnPos{
    GameData *gd = [GameData sharedInstance];
    NSString *className = gd.players[0][@"playerName"];
    _panda = [GameCharacter gcWithName:className wihtGameScene:_gameScene];

    _panda.position = spawnPos;

    self.contentSize = [CCDirector sharedDirector].viewSize;
    [_bgLayer addChild:_panda z:50];
    [self setPlayerFaceTo];

    if (gd.players.count > 1) {
        GameCharacter *followGC = nil;
        GameCharacter *targetGC = _panda;
        NSInteger maxFollowCount = MIN(2, gd.players.count-1);
        for (int i = 1; i <= maxFollowCount; i++) {
            className = gd.players[i][@"playerName"];
            followGC = [GameCharacter gcWithName:className wihtGameScene:_gameScene];
            [_bgLayer addChild:followGC];
            [followGC follow:targetGC];
            targetGC = followGC;
        }
    }

    self.userInteractionEnabled = YES;

    _walkableTiles = [NSMutableArray array];
    [self initWalkableTiles];

    _npcArray = [NSMutableArray array];
    _interactThingAry = [NSMutableArray array];
    _followAry = [NSMutableArray array];
}

但是在第一个方法中,对瓦块坐标要做一些修正以居中在瓦块显示,但在第二个方法中不需要修正,所以先要将这点重构之然后再调用后缀方法:

CGPoint spawnPos = [self getPlayerSpawnPos];
        spawnPos = [_mh centerObjectsPos:spawnPos];
        [self instanceSufInit:spawnPos];

第二个方法重构后的代码如下:

CGPoint spawnPos = [_mh positionForTilePos:tilePoint];
[self instanceSufInit:spawnPos];

现在2个方法共享同样的前缀和后缀方法,也消除了冗余代码,我们就这样完成了本次重构.

Cocos2D两个方法的重构一例的更多相关文章

  1. 获取网页URL地址及参数等的两种方法(js和C#)

    转:获取网页URL地址及参数等的两种方法(js和C#) 一 js 先看一个示例 用javascript获取url网址信息 <script type="text/javascript&q ...

  2. ant中调用外部ant任务的两种方法

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...

  3. [转]Delphi调用cmd的两种方法

    delphi调用cmd的两种方法vars:string;begins:='cmd.exe /c '+edit1.Text+' >c:\1.txt';winexec(pchar(s),sw_hid ...

  4. C++调用DLL有两种方法——静态调用和动态调用

    C++调用DLL有两种方法——静态调用和动态调用 标签: dllc++winapinullc 2011-09-09 09:49 11609人阅读 评论(0) 收藏 举报  分类: cpp(30)  [ ...

  5. CSS实现背景图尺寸不随浏览器大小而变化的两种方法

    一些网站的首页背景图尺寸不随浏览器缩放而变化,本例使用CSS 实现背景图尺寸不随浏览器缩放而变化,方法一. 把图片作为background,方法二使用img标签.喜欢的朋友可以看看   一些网站的首页 ...

  6. RAC时间同步的两种方法

    集群时间同步服务在集群中的两个 Oracle RAC 节点上执行以下集群时间同步服务配置.Oracle Clusterware 11g 第 2 版及更高版本要求在部署了 Oracle RAC 的集群的 ...

  7. SERVLET中的doGet与doPost两个方法之间的区别

    get和post是http协议的两种方法,另外还有head, delete等 这两种方法有本质的区别,get只有一个流,参数附加在url后,大小个数有严格限制且只能是字符串.post的参数是通过另外的 ...

  8. lua中 table 元表中元方法的重构实现

    转载请标明出处http://www.cnblogs.com/zblade/ lua作为游戏的热更新首选的脚本,其优势不再过多的赘述.今天,我主要写一下如何重写lua中的元方法,通过自己的重写来实现对l ...

  9. 计算理论:NFA转DFA的两种方法

    本文将以两种方法实现NFA转DFA,并利用C语言实现. 方法二已利用HNU OJ系统验证,方法一迷之WA,但思路应该是对的,自试方案,测试均通过. (主要是思路,AC均浮云,大概又有什么奇怪的Case ...

随机推荐

  1. ●ZOJ 2112 Dynamic Rankings

    ●赘述题目 对于一个长为n(n<50000)的序列(序列中的数小于1000000000),现有如下两种指令: Q a b c:询问区间[a,b]中第c小的数. C p b:将序列中的从左往右数第 ...

  2. Codeforces Round #402 (Div. 1)

    A题卡壳了,往离线倒着加那方面想了会儿,后来才发现方向错了,二十多分钟才过掉,过了B后做D,想法好像有点问题,最后只过两题,掉分了,差一点回紫. AC:AB Rank:173 Rating:2227- ...

  3. hdu5652 India and China Origins(并查集)

    India and China Origins  Accepts: 49  Submissions: 426  Time Limit: 2000/2000 MS (Java/Others)  Memo ...

  4. hdu3487 splay树

    Play with Chain Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  5. bzoj5100 [POI2018]Plan metra 构造

    5100: [POI2018]Plan metra Time Limit: 40 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 189  Sol ...

  6. Git与Github的基本概念

    git git是一个分布式版本控制系统,在这里就要介绍一下什么是版本控制:参考至维基百科 版本控制(Revision control)是维护工程蓝图的标准作法,能追踪工程蓝图从诞生一直到定案的过程.此 ...

  7. Linux学习之CentOS(十五)----磁盘管理之 启动挂载(转)

    启动挂载 /etc/fstab 及 /etc/mtab 刚刚上面说了许多,那么可不可以在启动的时候就将我要的文件系统都挂好呢?这样我就不需要每次进入 Linux 系统都还要在挂载一次呀!当然可以啰!那 ...

  8. input中v-model和value不能同时调用时解决方案

    <input type="text" v-model="keyWord" value="请输入地名地址" > 当使用如上代码时, ...

  9. AsyncLocal 与 async await

    大家来看一张图 先猜猜看为什么会这样 关于async await的原理 建议查看 https://blog.csdn.net/brook_shi/article/details/50803957 这篇 ...

  10. Linux文件管理笔记

    1)Linux识别磁盘:Linux通过不同的设备节点区分各个分区,节点名字的由磁盘名加分区号组成.例如,驱动器/dev/hba上的第一个分区叫做/dev/hba1,驱动器/dev/sdc上的第七个分区 ...