改写《魔塔》中篇05:重构代码之控制层

         写在前面:中期阶段我们只是按照书上的方式来介绍重构代码的过程,由于版本等原因,粘贴出来的代码已经不符合我们的需要。所以具体改动的代码以中期阶段项目里面的源码文件为准,项目源码下载请移步改写《魔塔》中篇06:善后工作和注意事项(附:中期阶段项目下载)。还有我们对原书中的项目进行了一些改动,包括用CCArray替换了CCMutableArray,增加了用于勇士初始化的getSpriteFrame方法等,因此,大家要注意项目源码改动的地方,并且留意文档注释。  

       前面一篇,我们抽象出了Hero类,增加了Singleton容器类,并用其创建了动画管理器AnimationManager和一个存放全局变量的类Global。目前的GameLayer类看起来清爽了很多,地图和勇士的初始化和相关方法都移到相关的类中,仅剩余了下面几个部分。

     (1)setSceneScrollPosition方法,用于根据勇士位置计算场景滚动的距离。

     (2)一个定时器方法,用于每帧调用setSceneScrollPosition

     (3)关闭按钮及其对应的onClick方法

     (4)4个方向按钮及onClick方法

       大家应该已经看出,后面两项也可以从GameLayer中分离出来,因为它们并不属于游戏内容相关的对象,可以把它们归结为控制层面的一部分。因此,我们最好创建一个控制层来统一管理相关的按钮。控制层应该作为一个独立的CCLayer,它的zOrder需要比GameLayer更高。首先创建一个空的类,即ControlLayer,它应该包括CCLayer标准的初始化方法和按钮点击事件的回调函数,ControlLayer的头文件代码如下:

#ifndef __CONTROL_LAYER_H__
#define __CONTROL_LAYER_H__

#include "MTGame.h"

using namespace cocos2d;

class ControlLayer:public CCLayer
{
	ControlLayer(void);
	~ControlLayer(void);
	//node方法会调用此函数
	virtual bool init();
	//方向按钮点击事件的回调
	void menuCallBackMove(CCObject* pSender);
	//关闭按钮点击事件的回调
	void menuCloseCallBack(CCObject* pSender);
	//使用CCLayer标准的创建实例的方式,声明node方法
	LAYER_NODE_FUNC(ControlLayer);
};
#endif

ControlLayer的代码文件中的具体实现只需要将GameLayer中的相关代码赋值过来即可:

#include "MTGame.h"
ControlLayer::ControlLayer(void)
{
}

ControlLayer::~ControlLayer(void)
{
}

bool ControlLayer::init()
{
	if(! CCLayer::init())
	{
	   return false;
	}
	//创建关闭按钮
	CCMenuItemImage *pCloseItem = CCMenuItemImage::itemFromNormalImage(
            "CloseNormal.png",
            "CloseSelected.png",
            this,
            menu_selector(ControlLayer::menuCloseCallback));
        pCloseItem->setPosition(ccp(CCDirector::sharedDirector()->getWinSize().width - 20, 20));
		CCMenu* pMenu = CCMenu::menuWithItems(pCloseItem, NULL);
        pMenu->setPosition(CCPointZero);
        this->addChild(pMenu, 1);
	//2.创建方向按钮
	CCMenuItem *down=CCMenuItemFont::itemFromString("down",this,menu_selector(ControlLayer::menuCallBackMove));
	CCMenuItem *left=CCMenuItemFont::itemFromString("left",this,menu_selector(ControlLayer::menuCallBackMove));
	CCMenuItem *right=CCMenuItemFont::itemFromString("right",this,menu_selector(ControlLayer::menuCallBackMove));
	CCMenuItem *up=CCMenuItemFont::itemFromString("up",this,menu_selector(ControlLayer::menuCallBackMove));
	CCMenu *menu=CCMenu::menuWithItems(down,left,right,up,NULL);

	//为方便查找,给每个menuItem设置tag
	down->setTag(kDown);
	left->setTag(kLeft);
	right->setTag(kRight);
	up->setTag(kUp);

	//菜单项按照间距水平排列
	menu->alignItemsHorizontallyWithPadding(50);
	addChild(menu);
        return true;
}

void ControlLayer::menuCloseCallBack(CCObject* pSender)
{
	CCDirector::sharedDirector()->end();
}

void ControlLayer::menuCallBackMove(CCObject* pSender)
{
	CCNode *node=(CCNode *)pSender;
	//按钮的tag就是将要行走的方向
	int targetDirection=node->getTag();
	sGlobal->hero->move((HeroDirection)targetDirection);
}

      最后,我们修改GameScene的init方法,在里面新建一个ControlLayer实例,并把它加为自己的孩子节点:

//新建一个ControlLayer实例
ControlLayer *controlLayer=ControlLayer::node();
CC_BREAK_IF(!controlLayer);
//将ControlLayer实例添加到场景中
scene->addChild(controlLayer);



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值