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

如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! 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. 数论:px+py 不能表示的最大数为pq-p-q的证明

    对于互质的两个数p,q,px+py 不能表示的最大数为pq-p-q. 证明: 先证:pq-p-q不能被px+py表示. 假设pq-p-q可以被px+py表示 那么 px+py=pq-p-q       ...

  2. Polya计数

    Let it Bead Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5365   Accepted: 3585 Descr ...

  3. 【小小复习·大米饼】

    (一)数位DP模板 ·LIS的数位DP: ·含b进制数个数+数形结合的数位DP ·平衡数的数位DP: (二)网络流问题 ·Edmonds_Karp:(见书)·Dinic(见书)·ISAP(见书)·例题 ...

  4. 例10-2 uva12169(扩展欧几里得)

    题意:已知xi=(a*xi-1+b) mod 10001,且告诉你x1,x3.........x2*t-1,让你求出其偶数列 思路: 枚举a,然后通过x1,x3求出b,再验证是否合适 1.设a, b, ...

  5. bzoj1293[SCOI2009]生日礼物 尺取法

    1293: [SCOI2009]生日礼物 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2838  Solved: 1547[Submit][Stat ...

  6. Python【第四课】 装饰器

    本篇内容 什么是装饰器 装饰器需要遵循的原则 实现装饰器的知识储备 高阶函数 函数嵌套 闭包函数 无参函数 装饰器示例 1.什么是装饰器 器即函数 装饰即修饰,意指为其他函数添加新功能 装饰器定义:本 ...

  7. ScalaPB(0): 找寻合适的内部系统微服务集成工具

    前一段时间我们探讨了SDP的一个基于集群的综合数据平台解决方案,由多种数据库组成,包括:JDBC, Cassandra 及MongoDB.其中Cassandra和MongoDB属于分布式数据库,可以在 ...

  8. 以太坊区块链Java(EthereumJ)学习笔记:概述

    本系列文章介绍以太坊区块链基于Java语言的解决方案.通过介绍EthereumJ定义的主要模块和Class,希望为大家学习和使用EthereumJ提供一些帮助. 整体架构 以太坊的Java解决方案主要 ...

  9. js 数字前面自动补零

    num传入的数字,n需要的字符长度        function PrefixInteger(num, n) {            return (Array(n).join(0) + num) ...

  10. Linux sort -n 与 -g 排序对比

    公司业务需要,天天用awk统计数值然后排序,出问题了,如下: count.sh 是一个统计脚本,把awk输出的值按占比.条数.类型 在重新输出 awk -F\| '{print $16}' *MQTT ...