使用TileMap制作游戏,在cocos2d-x中使用(二)

本篇博客出自阿修罗道,转载请注明出处:http://blog.csdn.net/fansongy/article/details/8877118


书接前文。

创造出世界之后要制定规则。游戏中有些地方是不可以穿过的。有些地方是会触发特殊效果的。现在来实现。

墙壁、石堆、牌子这些都是不可以穿过的。

首先在TileMap中编辑一下,大概方法是创建一个新层,专门负责碰撞部分。

具体可见:子龙翻译的 http://www.cnblogs.com/andyque/archive/2011/05/03/2033620.html 

编辑好了之后保存,替换到工程中。

开始编码。

首先要取得控制层,另外这层也不能显示出来。

头文件中增加:

[cpp]  view plain copy print ?
  1. CCTMXLayer* m_meta;  

在init中显示tmx之前加入:

[cpp]  view plain copy print ?
  1. m_meta = m_tileMap->layerNamed("Meta");  
  2. m_meta->setVisible(false);  

接下来是Gid的转换。将点的坐标转化到相应的格子中,即取得究竟想获取信息的贴图是哪张。


使用TileMap制作游戏,在cocos2d-x中使用(二)_第1张图片

没找到Qt版本的怎么显示这个数字。另外似乎没有写好的函数,有的话请留言告诉一下 哈 。自己写:

[cpp]  view plain copy print ?
  1. CCPoint HelloWorld::posToMapBlock(CCPoint pos)  
  2. {  
  3.     int x = pos.x / m_tileMap->getTileSize().width;  
  4.     int y = ( m_tileMap->getContentSize().height - pos.y)/m_tileMap->getTileSize().height;  
  5.     return ccp(x,y);  
  6. }  


有了这个坐标点就可以找出Gid了。这东西就是个Key。value就是图源的属性表,以字典形式返回。

这部分加在响应里。

[cpp]  view plain copy print ?
  1. CCPoint pConverted = posToMapBlock(ccp(moveTo.x,moveTo.y));  
  2. int tileGID = m_meta->tileGIDAt(pConverted);  
  3. if(tileGID)  
  4. {  
  5.     CCDictionary* pro = m_tileMap->propertiesForGID(tileGID);  
  6.     if(pro)  
  7.     {  
  8.         CCString* collision =const_cast<CCString*>(pro->valueForKey("Collidable"));  
  9.         if(collision && collision->compare("true") == 0)  
  10.         {  
  11.             return;  
  12.         }  
  13.     }  
  14. }  


行了,有这个gid返回的字典,就可以取到在地图中设定的信息。数据、消息一到位,也就基本完成了。

编译运行,就成了。

有限制不够,还要有奖励。地图上的西瓜可以吃掉,加个血什么的。

新建一个层,专门放西瓜。把之前的西瓜挪到这层中。在meta层用绿色的块填充这部分,并设置属性。

具体可以看一开始那个外链。

接下来就是要弄一个层专门显示吃掉的西瓜数了。

自己写个ScoreScene:

[cpp]  view plain copy print ?
  1. #pragma once  
  2. #include "cocos2d.h"  
  3. USING_NS_CC;  
  4.   
  5. class ScoreLayer:public CCLayer  
  6. {  
  7. public:  
  8.     CREATE_FUNC(ScoreLayer);  
  9.     virtual bool init();  
  10.     void numberadd();  
  11. private:  
  12.     CCLabelTTF* m_label;  
  13.     int m_score;  
  14. };  

[cpp]  view plain copy print ?
  1. #include "ScoreLayer.h"  
  2.   
  3. bool ScoreLayer::init()  
  4. {  
  5.     bool bRet = false;  
  6.     do   
  7.     {  
  8.         CC_BREAK_IF(! CCLayer::init());  
  9.     CCSize winSize = CCDirector::sharedDirector()->getWinSize();  
  10.     m_label = CCLabelTTF::create();  
  11.     m_label->initWithString("0","Verdana-Bold",18);  
  12.     m_label->setColor(ccc3(0,0,0));  
  13.     int magin = 10;  
  14.     m_label->setPosition(ccp(winSize.width - m_label->getContentSize().width/2 - magin,  
  15.         m_label->getContentSize().height + magin));  
  16.     m_score = 0;  
  17.     this->addChild(m_label);  
  18.     bRet = true;  
  19.     }while(0);  
  20.     return bRet;  
  21. }  
  22. void ScoreLayer::numberadd()  
  23. {  
  24.     m_score++;  
  25.     m_label->setString(CCString::createWithFormat("%d",m_score)->getCString());     
  26. }  

没什么可解释的。

在HelloWorld.cpp中创建一个全局变量:

[cpp]  view plain copy print ?
  1. ScoreLayer *score_layer;  


在scene中加入这个Layer:

[cpp]  view plain copy print ?
  1. score_layer = ScoreLayer::create();  
  2. CC_BREAK_IF(! score_layer);  
  3. scene->addChild(score_layer);  

这样就可以显示了,更改数值的部分自然是要放到响应中了。

[cpp]  view plain copy print ?
  1. CCString* collectable = const_cast<CCString*>(pro->valueForKey("Collectable"));  
  2. if(collectable && collectable->compare("true") == 0)  
  3. {  
  4.     //此处地图已经更改过了,将西瓜放在foreground上了。  
  5.     m_meta->removeTileAt(pConverted);  
  6.     m_foreground->removeTileAt(pConverted);  
  7.     score_layer->numberadd();  
  8. }  

此处要注意。这个层是与HelloWorld同级的。helloWorld是主场景,自然是要动的。这个层是状态场景,不可以移动。

它们都应该是在Scene层的管制之下,互相之间是不应该有关联的。

此处我是用全局变量了,这种最省事的方法。大型项目的话应该封一个管理的类,不然该乱了。

行了,编译运行就成了。

0资源分 代码:http://download.csdn.net/detail/fansongy/5323719

你可能感兴趣的:(使用TileMap制作游戏,在cocos2d-x中使用(二))