Cocos2d-x源代码解析(1)——地图模块(3)
接上一章《Cocos2d-x源代码解析(1)——地图模块(2)》
通过前面两章的分析,我们能够知道cocos将tmx的信息结构化到 CCTMXMapInfo。CCTMXTilesetInfo,CCTMXLayerInfo之中。
当中CCTMXMapInfo存储地图的信息包扩下面几块信息:
- Map orientation (hexagonal, isometric or orthogonal)
- Tile size
- Map size
- Layers (an array of TMXLayerInfo objects)
- Tilesets (an array of TMXTilesetInfo objects)
- ObjectGroups (an array of TMXObjectGroupInfo objects)
CCTMXTilesetInfo存储瓦片信息包含:
- Tileset name
- Tileset spacing
- Tileset margin
- size of the tiles
- Image used for the tiles
- Image size
CCTMXLayerInfo存储层的信息包含:
-
Layer name
- Layer size
- Layer opacity at creation time (it can be modified at runtime)
- Whether the layer is visible (if it's not visible, then the CocosNode won't be created)
接下来,我们分析cocos怎样通过这些信息,生成地图的图像:
首先我们看一个重要的函数buildWithMapInfo
void CCTMXTiledMap::buildWithMapInfo(CCTMXMapInfo* mapInfo)
{
m_tMapSize = mapInfo->getMapSize();
m_tTileSize = mapInfo->getTileSize();
m_nMapOrientation = mapInfo->getOrientation(); CC_SAFE_RELEASE(m_pObjectGroups);
m_pObjectGroups = mapInfo->getObjectGroups();
CC_SAFE_RETAIN(m_pObjectGroups); CC_SAFE_RELEASE(m_pProperties);
m_pProperties = mapInfo->getProperties();
CC_SAFE_RETAIN(m_pProperties); CC_SAFE_RELEASE(m_pTileProperties);
m_pTileProperties = mapInfo->getTileProperties();
CC_SAFE_RETAIN(m_pTileProperties); int idx=0; CCArray* layers = mapInfo->getLayers();
if (layers && layers->count()>0)
{
CCTMXLayerInfo* layerInfo = NULL;
CCObject* pObj = NULL;
CCARRAY_FOREACH(layers, pObj)
{
layerInfo = (CCTMXLayerInfo*)pObj;
if (layerInfo && layerInfo->m_bVisible)
{
CCTMXLayer *child = parseLayer(layerInfo, mapInfo);
addChild((CCNode*)child, idx, idx); // update content size with the max size
const CCSize& childSize = child->getContentSize();
CCSize currentSize = this->getContentSize();
currentSize.width = MAX( currentSize.width, childSize.width );
currentSize.height = MAX( currentSize.height, childSize.height );
this->setContentSize(currentSize); idx++;
}
}
}
}
这个函数首相将地图信息赋给map类。接下来对于每一个layer进行处理,重要的函数是parseLayer,这个函数是将layer的信息处理好而且加上sprite,并生成CTMXlayer对象。
因此我们须要分析parseLayer函数和CTMXlayer类。
首先我们看CTMXlayer的声明:
class CC_DLL CCTMXLayer : public CCSpriteBatchNode
{
/** size of the layer in tiles */
CC_SYNTHESIZE_PASS_BY_REF(CCSize, m_tLayerSize, LayerSize);
/** size of the map's tile (could be different from the tile's size) */
CC_SYNTHESIZE_PASS_BY_REF(CCSize, m_tMapTileSize, MapTileSize);
/** pointer to the map of tiles */
CC_SYNTHESIZE(unsigned int*, m_pTiles, Tiles);
/** Tileset information for the layer */
CC_PROPERTY(CCTMXTilesetInfo*, m_pTileSet, TileSet);
/** Layer orientation, which is the same as the map orientation */
CC_SYNTHESIZE(unsigned int, m_uLayerOrientation, LayerOrientation);
/** properties from the layer. They can be added using Tiled */
CC_PROPERTY(CCDictionary*, m_pProperties, Properties);
public:
/**
* @js ctor
* @lua NA
*/
CCTMXLayer();
/**
* @js NA
* @lua NA
*/
virtual ~CCTMXLayer(); /** creates a CCTMXLayer with an tileset info, a layer info and a map info */
static CCTMXLayer * create(CCTMXTilesetInfo *tilesetInfo, CCTMXLayerInfo *layerInfo, CCTMXMapInfo *mapInfo); /** initializes a CCTMXLayer with a tileset info, a layer info and a map info
* @lua NA
*/
bool initWithTilesetInfo(CCTMXTilesetInfo *tilesetInfo, CCTMXLayerInfo *layerInfo, CCTMXMapInfo *mapInfo); /** dealloc the map that contains the tile position from memory.
Unless you want to know at runtime the tiles positions, you can safely call this method.
If you are going to call layer->tileGIDAt() then, don't release the map
*/
void releaseMap(); /** returns the tile (CCSprite) at a given a tile coordinate.
The returned CCSprite will be already added to the CCTMXLayer. Don't add it again.
The CCSprite can be treated like any other CCSprite: rotated, scaled, translated, opacity, color, etc.
You can remove either by calling:
- layer->removeChild(sprite, cleanup);
- or layer->removeTileAt(ccp(x,y));
@js getTileGIDAt
*/
CCSprite* tileAt(const CCPoint& tileCoordinate); /** returns the tile gid at a given tile coordinate.
if it returns 0, it means that the tile is empty.
This method requires the the tile map has not been previously released (eg. don't call layer->releaseMap())
@js tileGIDAt
*/
unsigned int tileGIDAt(const CCPoint& tileCoordinate); /** returns the tile gid at a given tile coordinate. It also returns the tile flags.
This method requires the the tile map has not been previously released (eg. don't call [layer releaseMap])
@js tileGIDAt
@lua NA
*/
unsigned int tileGIDAt(const CCPoint& tileCoordinate, ccTMXTileFlags* flags); /** sets the tile gid (gid = tile global id) at a given tile coordinate.
The Tile GID can be obtained by using the method "tileGIDAt" or by using the TMX editor -> Tileset Mgr +1.
If a tile is already placed at that position, then it will be removed.
*/
void setTileGID(unsigned int gid, const CCPoint& tileCoordinate); /** sets the tile gid (gid = tile global id) at a given tile coordinate.
The Tile GID can be obtained by using the method "tileGIDAt" or by using the TMX editor -> Tileset Mgr +1.
If a tile is already placed at that position, then it will be removed. Use withFlags if the tile flags need to be changed as well
*/ void setTileGID(unsigned int gid, const CCPoint& tileCoordinate, ccTMXTileFlags flags); /** removes a tile at given tile coordinate */
void removeTileAt(const CCPoint& tileCoordinate); /** returns the position in points of a given tile coordinate
* @js getPositionAt
*/
CCPoint positionAt(const CCPoint& tileCoordinate); /** return the value for the specific property name
* @js getProperty
*/
CCString *propertyNamed(const char *propertyName); /** Creates the tiles */
void setupTiles(); /** CCTMXLayer doesn't support adding a CCSprite manually.
* @warning addchild(z, tag); is not supported on CCTMXLayer. Instead of setTileGID.
* @lua NA
*/
virtual void addChild(CCNode * child, int zOrder, int tag);
/** super method
* @lua NA
*/
void removeChild(CCNode* child, bool cleanup); inline const char* getLayerName(){ return m_sLayerName.c_str(); }
inline void setLayerName(const char *layerName){ m_sLayerName = layerName; }
private:
CCPoint positionForIsoAt(const CCPoint& pos);
CCPoint positionForOrthoAt(const CCPoint& pos);
CCPoint positionForHexAt(const CCPoint& pos); CCPoint calculateLayerOffset(const CCPoint& offset); /* optimization methods */
CCSprite* appendTileForGID(unsigned int gid, const CCPoint& pos);
CCSprite* insertTileForGID(unsigned int gid, const CCPoint& pos);
CCSprite* updateTileForGID(unsigned int gid, const CCPoint& pos); /* The layer recognizes some special properties, like cc_vertez */
void parseInternalProperties();
void setupTileSprite(CCSprite* sprite, CCPoint pos, unsigned int gid);
CCSprite* reusedTileWithRect(CCRect rect);
int vertexZForPos(const CCPoint& pos); // index
unsigned int atlasIndexForExistantZ(unsigned int z);
unsigned int atlasIndexForNewZ(int z);
protected:
//! name of the layer
std::string m_sLayerName;
//! TMX Layer supports opacity
unsigned char m_cOpacity; unsigned int m_uMinGID;
unsigned int m_uMaxGID; //! Only used when vertexZ is used
int m_nVertexZvalue;
bool m_bUseAutomaticVertexZ; //! used for optimization
CCSprite *m_pReusedTile;
ccCArray *m_pAtlasIndexArray; // used for retina display
float m_fContentScaleFactor;
};
尽管有一大堆的属性和函数,可是归根结底他是一个CCSpriteBatchNode对象,因为地图中非常多图片是同样的。CCSpriteBatchNode就是cocos2d-x为了减少渲染批次而建立的一个专门管理精灵的类。
然后是函数parseLayer
CCTMXLayer * CCTMXTiledMap::parseLayer(CCTMXLayerInfo *layerInfo, CCTMXMapInfo *mapInfo)
{
CCTMXTilesetInfo *tileset = tilesetForLayer(layerInfo, mapInfo);
CCTMXLayer *layer = CCTMXLayer::create(tileset, layerInfo, mapInfo); // tell the layerinfo to release the ownership of the tiles map.
layerInfo->m_bOwnTiles = false;
layer->setupTiles(); return layer;
}
这个函数又分为3步
第一步tilesetForLayer是拿到随意一块属于这个layer的tile。
第二步是依据layerInfo创建一个真正的层信息。
第三步是将tiled增加到这个层中去。
Cocos2d-x源代码解析(1)——地图模块(3)的更多相关文章
- Android xUtils3源代码解析之网络模块
本文已授权微信公众号<非著名程序猿>原创首发,转载请务必注明出处. xUtils3源代码解析系列 一. Android xUtils3源代码解析之网络模块 二. Android xUtil ...
- Cocos2d-x源代码解析(1)——地图模块(1)
cocos通过加载tiled 生成的tmx文件来生成游戏地图.本文主要分析cocos加载地图模块的源代码. 如图所看到的,地图加载模块由以上几个类组成. 对外的入口是类CCTMXTiledMap, ...
- thttpd源代码解析 定时器模块
thttpd源代码解析 定时器模块 thttpd是很轻量级的httpserver,可运行文件仅50kB.名称中的第一个t表示tiny, turbo, 或throttling 与lighttpd.mem ...
- 《nginx源代码解析》系列分享专栏
<nginx源代码解析>系列分享专栏 解析nginx源代码,从main函数开始,一步步解读nginx运行原理,同时进行nginx第三方模块的开发,努力做到知其然,知其所以然 <ngi ...
- linux device tree源代码解析--转
//Based on Linux v3.14 source code Linux设备树机制(Device Tree) 一.描述 ARM Device Tree起源于OpenFirmware (OF), ...
- Android源代码解析之(十三)-->apk安装流程
转载请标明出处:一片枫叶的专栏 上一篇文章中给大家分析了一下android系统启动之后调用PackageManagerService服务并解析系统特定文件夹.解析apk文件并安装的过程,这个安装过程实 ...
- Spark技术内幕:Client,Master和Worker 通信源代码解析
Spark的Cluster Manager能够有几种部署模式: Standlone Mesos YARN EC2 Local 在向集群提交计算任务后,系统的运算模型就是Driver Program定义 ...
- Spring源代码解析
Spring源代码解析(一):IOC容器:http://www.iteye.com/topic/86339 Spring源代码解析(二):IoC容器在Web容器中的启动:http://www.itey ...
- python 解析XML python模块xml.dom解析xml实例代码
分享下python中使用模块xml.dom解析xml文件的实例代码,学习下python解析xml文件的方法. 原文转自:http://www.jbxue.com/article/16587.html ...
随机推荐
- Linux cp -a用法
对于cp -a最主要的用法是在保留原文件属性的前提下复制文件.其实还有个很好的用法,如下: 大家知道linux下复制目录可以通过,cp -r dirname destdir 但是这样复制的目录属性会发 ...
- Ext4功能和文件系统的简单功能
Linux kernel 自 2.6.28 開始正式支持新的文件系统 Ext4. Ext4 是 Ext3 的改进版,改动了 Ext3 中部分重要的数据结构,而不只像 Ext3 对 Ext2 那样,不过 ...
- bellman_ford算法
给定一个源点,求最短路径,那么存在以源点为根的最短路径树因为最短路径具有最优子结构的性质,所以我们可以先求出树的第一层,然后再求出树的第二层,以此类推bellman_ford算法就是按照这种思想求最短 ...
- Hadoop认知--在不同的阶段
入门阶段 出于兴趣,及工作中的简单有用,大约经过1个月的时间,完毕了对Hadoop的基本认知. 在这个月中我干了例如以下几件事 1.大体看了<Hadoop权威指南>.把里面的代码手工码了一 ...
- linux 经常使用配置
教研室用的非常旧的fedora14,装一些软件和下载东西的时候比較蛋疼,恰巧ubuntu14.04 公布,于是安装试试,顺便记录下经常使用的配置,备忘. 1. 制作镜像,比較老的主板,写入方式选择US ...
- VS2008下直接安装Boost库1.46.1版本号
Boost图书馆是一个移植.提供源代码C++库.作为一个备份标准库,这是C++发动机之间的一种标准化的过程. Boost图书馆由C++图书馆标准委员会工作组成员发起,一些内容有望成为下一代C++标准库 ...
- 采用PopupWin控制消息推送功能
最近的项目需要,急需实现消息推送功能.接连试了很多办法,让我们用JavaScript为了实现啊,其效果是不咋好,最后,我发现了一个PopupWin这个,看着眼前的成绩不错,开始使用. 1.准备工作.先 ...
- 重新想象 Windows 8 Store Apps (23) - 文件系统: 文本的读写, 二进制的读写, 流的读写, 最近访问列表和未来访问列表
原文:重新想象 Windows 8 Store Apps (23) - 文件系统: 文本的读写, 二进制的读写, 流的读写, 最近访问列表和未来访问列表 [源码下载] 重新想象 Windows 8 S ...
- Nubia Z5S 官方4.4 201内測版 内核版本号信息
从egl推断内核的的版本号: OpenGL ES Shader Compiler Version: E031.24.00.14 Build Date: 04/29/14 Tue Local Branc ...
- A. Initial Bet(Codeforces Round #273)
A. Initial Bet time limit per test 1 second memory limit per test 256 megabytes input standard input ...