改写《魔塔》中篇01:重构代码之分离场景和图层

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

      到目前为止,我们头疼地发现所有方法都是在同一个类(HelloWorldScene)里实现的。随着新功能的增加,代码变得异常臃肿,阅读和修改也变得越发困难。为了以后的可持续发展,让我们果断暂停新功能的开发,开始对老代码进行重构。

      首先我们对HelloWorldScene既包含了场景(CCScene)又包含了层(CCLayer)的做法表示不满:从名字来看,它是个场景(CCScene),可层(CCLayer)部分它也包含进去了。于是干脆将它分离成两个类:GameScene和GameLayer。

      GameScene类继承于CCScene,主要负责游戏主场景的创建,它可以与以后游戏中各种场景进行切换,比如主菜单场景。同时,它负责创建游戏主场景内的各个CCLayer,包括地图层,控制按钮层,对话框层和特效层等。

      GameLayer继承CCLayer,负责绘制游戏主界面的内容,包括地图,勇士和战斗效果等。

好了,现在来创建GameScene和GameLayer这两个类。

在这之前,首先创建一个公用文件MTGame.h,里面包含了项目中需要公用的类的头文件。这样做的好处是管理方便,所有头文件一目了然。缺点是你修改某个类的定义的时候,会引起其他所有类的重新编译。对于我们目前的游戏来说,这点牺牲还是值得的。如果你的游戏复杂到了一定程度,编译需要很长时间,那么还是老老实实地分别管理头文件比较好。言归正传,MTGame.h文件如下:

	#ifndef __MTGAME_H__
	#define __MTGAME_H__
	
	#include "cocos2d.h"
	#include "GameLayer.h"
	#include "GameScene.h"
	
	#endif

GameScene中需要提供一个静态方法showGameScene,用来生成一个新的游戏主界面实例,头文件代码如下:

	#ifndef __GAME_SCENE_H__
	#define __GAME_SCENE_H__
	
	//包含公用头文件
	#include "MTGame.h"
	//使用cocos2d命名空间
	using namespace cocos2d;
	//GameScene继承CCScene
	class GameScene : public CCScene
	{
	public:
		GameScene(void);
		~GameScene(void);
		//静态方法用于创建新的游戏主界面的实例
		static CCScene* playNewGame();
		//初始化函数
		virtual bool init();
		//Scene的静态创建方法(2.0以后有所变化)
		CREATE_FUNC(GameScene)
	};
	
	#endif

       GameScene的代码文件(cpp)如下,首先会使用CCScenecreate方法创建一个实例,然后调用GameLayercreate方法创建layer的实例,并将其加入到scene当中:

	#include "GameScene.h"
	
	GameScene::GameScene(void)
	{
	}
	
	GameScene::~GameScene(void)
	{
	}
	
	bool GameScene::init()
	{
		//新建一个GameLayer实例
		GameLayer* gamelayer=GameLayer::create();
		//将GameLayer实例添加到场景中
		this->addChild(gamelayer,kGameLayer,kGameLayer);
		//新建一个ControlLayer实例
		ControlLayer* controlLayer=ControllerLayer::create();
		//将ControlLayer实例添加到场景中
		this->addChild(controlLayer,kControlLayer,kControlLayer);
		return true;
	}
	
	CCScene* GameScene::playNewGame()
	{
	    GameScene* scene=NULL;
		do
		{
			scene=GameScene::create();
			CC_BREAK_IF(! scene);
		}while(0);
		return scene;
	}

    一定会有许多错误提示,那是因为一些变量或者方法并没有定义,不急,我们会在后面进行定义和添加。

    对于GameLayer类,我们先把原来HelloWorldScene.cppHelloWorld类中相关的代码复制出来,重命名为GameLayer即可。继续修改AppDelegate中创建场景的部分:

	// create a scene. it's an autorelease object
		CCScene *pScene = GameScene::playNewGame();
	
	    // run
	    pDirector->runWithScene(pScene);

当然,别忘了包含头文件“ #include "GameScene.h" ”。



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值