改写《魔塔》中篇02:重构代码之分离游戏地图类
2013-03-31 05:52
393 查看
写在前面:中期阶段我们只是按照书上的方式来介绍重构代码的过程,由于版本等原因,粘贴出来的代码已经不符合我们的需要。所以具体改动的代码以中期阶段项目里面的源码文件为准,项目源码下载请移步《改写《魔塔》中篇06:善后工作和注意事项(附:中期阶段项目下载)》。还有我们对原书中的项目进行了一些改动,包括用CCArray替换了CCMutableArray,增加了用于勇士初始化的getSpriteFrame方法等,因此,大家要注意项目源码改动的地方,并且留意文档注释。
我们已经将HelloWorldScene.cpp中的代码分离成GameScene和GameLayer两部分。可以看出GameScene类的功能已经相对单一了,但GameLayer类仍然内容驳杂。下面来想办法继续拆分GameLayer类。目前游戏主界面包含3个对象,即地图,勇士和控制按钮(关闭按钮和方向按钮)。因此可以将GameLayer中的方法按这3大类进行划分。
(1)地图类负责TMX地图的各项初始化操作以及Tilemap坐标系和cocos2d-x坐标系之间的转换。
(2)勇士类负责行走动画的创建,在地图上移动以及碰撞检测。
(3)控制层则包括关闭按钮和方向按钮的逻辑。
先分离地图对象。我们的游戏地图类在CCTMXTiledMap功能基础上,添加了额外的初始化操作:包括方便地获取各个层,开启纹理抗锯齿,以后可能会有的敌人以及NPC属性的读取。另外,Tilemap和cocos2d-x坐标系的转换以及碰撞检测也可以放在地图类中。现在,新建一个GameMap类,继承自CCTMXTiledMap,然后将需要实现的方法写在头文件里,具体代码如下:
#ifndef __GAME_MAP_H__ #define __GAME_MAP_H__ #include "MTGame.h" typedef enum { kNone = 1,//可以通行 kWall,//墙 kEnemy,//敌人 } CollisionType;//碰撞类型 using namespace cocos2d; //继承自CCTMXTiledMap class GameMap:public cocos2d::CCTMXTiledMap { //只读变量,获取地板层和墙壁层 CC_PROPERTY_READONLY(CCTMXLayer*,floorLayer,FloorLayer); CC_PROPERTY_READONLY(CCTMXLayer*,wallLayer,WallLayer); public: GameMap(void); ~GameMap(void); //静态方法,用于生成GameMap实例 static GameMap* gameMapWithTMXFile(const char* tmxFile); //TiledMap和cocos2d-x坐标系相互转换的方法 CCPoint tileCoordForPosition(CCPoint position); CCPoint positionForTileCoord(CCPoint tileCoord); protected: //TiledMap额外的初始化方法 void extraInit(); //开启各图层的纹理抗锯齿 void enableAnitiAliasForEachLayer(); }; #endif
在类的开始我们使用了CC_PROPERTY_READONLY宏,这是cocos2d-x引擎内嵌的宏,可以方便地声明变量的get和set方法,具体用法参见CCPlateformMacros.h。这里声明了两个protected的CCTMXLayer指针类型的变量,用来获取地板层和墙壁层。在cpp文件中,需要自己实现getter方法:
//返回地板层 CCTMXLayer* GameMap::getFloorLayer() { return floorLayer; } //返回墙壁层 CCTMXLayer* GameMap::getWallLayer() { return wallLayer; }
静态方法gameMapWithTMXFile用于生成GameMap实例。它遵循了cocos2d-x生成对象的规范:new一个对象,调用其init方法,设置对象为autorelease。具体代码如下:
//静态方法,用于生成GameMap实例 GameMap* GameMap::gameMapWithTMXFile(const char* tmxFile) { //new一个对象 GameMap* pRet=new GameMap(); //调用init方法 if(pRet->initWithTMXFile(tmxFile)) { //调用额外的init方法 pRet->extraInit(); //将实例放入autorerelease池,统一由引擎控制对象的生命周期 pRet->autorelease(); return pRet; } CC_SAFE_DELETE(pRet); return NULL; }
在gameMapWithTMXFile中除了调用CCTMXTiledMap自有的initWithTMXFile方法以外,还调用了我们自己定义的extraInit方法,用于进行一些额外的初始化操作。
//TiledMap额外的初始化方法 void GameMap::extraInit() { //开启各个图层的纹理抗锯齿 enableAnitiAliasForEachLayer(); //初始化地板层和墙壁层对象 floorLayer=this->layerNamed("floor"); wallLayer=this->layerNamed("wall"); } enableAnitiAliasForEachLayer方法用于开启TiledMap中所有层的纹理抗锯齿效果: void GameMap::enableAnitiAliasForEachLayer() { CCArray* pChildrenArray=this->getChildren(); CCSpriteBatchNode* child=NULL; CCObject* pObject=NULL; //遍历Tilemap的所有图层 CCARRAY_FOREACH(pChildrenArray,pObject) { child=(CCSpriteBatchNode*)pObject; if(!child) break; //给图层的纹理开启抗锯齿 child->getTexture()->setAntiAliasTexParameters(); } }
tileCoordForPosition,positionForTileCoord和checkCollision方法基本与前面HelloWorld中的实现一致,这里不再赘述(后面把checkCollision方法放在了新建的勇士类里)。最后在GameLayer中,只需要调用GameMap的gameMapWithTMXFile方法就可以很方便地创建游戏地图了,具体代码如下:
map=GameMap::gameMapWithTMXFile("0.tmx"); addChild(map);
相关文章推荐
- 改写《魔塔》中篇03:重构代码之分离勇士类
- 改写《魔塔》中篇01:重构代码之分离场景和图层
- 改写《魔塔》中篇04:重构代码之单例类
- 改写《魔塔》中篇05:重构代码之控制层
- 改写《魔塔》前篇01:绘制最简单的游戏地图
- 写了一段从图像中分离人物和背景的代码,本来想写成智能定位Breast的,可是时间不够,公司游戏开发任务太紧了。先发一段吧···以后有空再补上
- 游戏项目中运用到的设计模式(二)...策略模式(strategy)(《重构-改善既有代码的设计》读后做)
- 应该将游戏玩法与引擎代码分离
- 改写《魔塔》后篇06:传送点及地图切换(附:后期阶段项目下载)
- TYPagerController 简单,强大,高度定制,页面控制器,水平滚动内容和标题栏,包含多种barStyle。 TYPagerController v2.0 重构优化代码,分离出TYPager
- 改写《魔塔》后篇01:在地图上绘制怪物
- 用cocos-Android-1做魔塔游戏 地图实现
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(二十二)重构 – 让代码插上翅膀自由飞翔
- Winform打砖块游戏制作step by step第5节---重构代码,利用继承多态
- Winform打砖块游戏制作step by step第5节---重构代码,利用继承多态
- 再次重写贪吃蛇代码(多线程,有游戏的小地图)
- 代码重构--实践家的快乐游戏
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(二十二)重构 – 让代码插上翅膀自由飞翔
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(二十二)重构 – 让代码插上翅膀自由飞翔
- C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):(二十二)重构 – 让代码插上翅膀自由飞翔