转自:http://www.tuicool.com/articles/jUrqea
根据 http://www.raywenderlich.com/1163/how-to-make-a-tile-based-game-with-cocos2d 中的介绍来在cocos2d-x上实现。
文章内容:
一、Tiled工具的使用
二、Touch事件的检测,拖动和缩放操作
一、实现Tiled免费地图工具编辑
1、安装工具,从 Tiled Map Editor 下载并且安装,然后打开
按左上角那个new一个新地图:
地图大小:块的数量,并不是像素
块大小:就是1个方块的大小,地图由N个方块组成
然后创建地图资源,点击工具栏:地图-新图块
名称自定义,当然符合一般命名标准,- -切忌中文。
图像-浏览-选择下载的素材
其他定义根据刚刚新建地图的设置来,注意边距跟制作的图像有关系,上图我们看到每个小块都有1个1像素的透明黑边,其实这个就是为了块图之间能保证其正常像素不偏差,和unity3d中生成atlas是一个道理的,也可以设置padding调整,扯远了。哈哈
大家摸索下这些按钮就应该懂什么意思了。我制作好的图。
我设置了我的layer为Background
2、把TMX文件提供给cocos2d-x项目并且使用上去
右键-add files这步就不说了。
代码部分:
在HelloWorld的layer头文件增加2个关于tmx对象的定义,一个地图,一个地图层
Helloworld实现文件的操作
然后大胆地点击编译吧!
一启动就暂停了。
淡定,一看就知道是创建tmx map时候报错了。
我们观察下导入的TMX文件内容:
选中的部分就是需要改的,这里注意了:
因为我的地图文件png是放到下载下面的,然而编译时候,是不会存在../Downloads……这个目录。
我们改成直接就是Resource根目录:
再运行:
很帅是么? 这里我们注意看,地图显示的就是左下角,也就是制作的地图的(0,0)点在左下角对着屏幕左下角。下面将尝试地图的移动以及缩放等操作!
二、Touch事件的检测
virtual void registerWithTouchDispatcher(); virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent); //这个方法必须实现 virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);
TouchDelegate的一些事件。下面我们认识下这3个方法:
关于 virtual void registerWithTouchDispatcher(); 首先这个用来干嘛的呢?
/** @brief CCTouchDispatcher.
Singleton that handles all the touch events.
The dispatcher dispatches events to the registered TouchHandlers.
There are 2 different type of touch handlers:
- Standard Touch Handlers
- Targeted Touch Handlers
The Standard Touch Handlers work like the CocoaTouch touch handler: a set of touches is passed to the delegate.
On the other hand, the Targeted Touch Handlers only receive 1 touch at the time, and they can "swallow" touches (avoid the propagation of the event).
Firstly, the dispatcher sends the received touches to the targeted touches.
These touches can be swallowed by the Targeted Touch Handlers. If there are still remaining touches, then the remaining touches will be sent
to the Standard Touch Handlers.
@since v0.8.0
*/
上面是官方定义的CCTouchDispatcher的描述,我们知道有2种实现和处理触碰的消息,标准触碰、目标触碰。
http://cn.cocos2d-x.org/document/index/class?url=da/de4/classcocos2d_1_1_c_c_touch_dispatcher.html 这是官方中文翻译的一个解释。
标准触碰是统一处理所有的消息,而目标触碰就是单一的处理,并且能过滤其他消息。所以一般我们准确性触碰的处理建议还是使用目标触碰模式。
怎么启动Targeted Touch Handlers??
如果了解监听者模式的应该瞬间能理解,默认在初始化时候
1、设置
this->setTouchEnabled(true);
2、继承和实现
定义
virtual void registerWithTouchDispatcher();实现如下:
void HelloWorld::registerWithTouchDispatcher(){
CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0, true);
}
这里说一下,正常的监听者模式需要:使用前注册,使用后移除!当我们继承和实现了
registerWithTouchDispatcher
那么移除的操作会自动在OnExit时候执行,不需要我们去关心!
3、使用想要监听的触碰消息方法,注意一个触碰一定会有“开始”,所以
virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent); //这个方法必须实现
其他方法可以从CCTouchDispatcher定义里面查找。
三、iOS多点触碰的使用,实现双指缩放,单指拖动,双击自动缩放和移到目标位置!
注意:以下先说明怎么启动“标准触碰”方式,但这个方式我不建议,因为~~~后面会看到原因!
1、启动iOS端多点触碰,默认是关闭的
//open iOS multiple touch.
[__glView setMultipleTouchEnabled:YES];
把以上添加到ios目录中的AppController.mm程序启动回调里面。也就是默认iOS启动处理文件。
2、Layer检测触碰信息方法
2.1、需要启动
layer初始化时候启动触碰支持: this -> setTouchEnabled ( true );
2.2、继承实现触碰的方法
// optional virtual void ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent) {CC_UNUSED_PARAM(pTouches); CC_UNUSED_PARAM(pEvent);} virtual void ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent) {CC_UNUSED_PARAM(pTouches); CC_UNUSED_PARAM(pEvent);} virtual void ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent) {CC_UNUSED_PARAM(pTouches); CC_UNUSED_PARAM(pEvent);} virtual void ccTouchesCancelled(CCSet *pTouches, CCEvent *pEvent) {CC_UNUSED_PARAM(pTouches); CC_UNUSED_PARAM(pEvent);}
以上方法就是在CCTouchDelegateProtocol里面,注意观察和上述第一点说的目标触碰不一样就是,这里处理的是所有信息,从传参可看,pTouches代表了多点的意思。
通常大家从cocos2d-iPhone的例子中可以用
UITouch* touch1 = [[[event allTouches] allObjects] objectAtIndex:0]; UITouch* touch2 = [[[event allTouches] allObjects] objectAtIndex:1];没错,感觉CCSet是不是和NSSet很像呢?但我很肯定告诉你,这里是不一样的,CCSet并不拥有objectAtIndex这个方法,当然你也可以用它的迭代器去取每一个触碰点。
但我实践可以告诉你,结果并不如意。即使你固定这个CCTouch* touch1->GetID() == 0 来判断,用“标准触碰”来检测双指缩放,依旧会出现参杂的情况!参杂也就是明明2只手指,但却突然会检测到是1只手指的时候!!kiding me?
经过参看CCScrollView中,我发现,原来注册使用“目标触碰”来处理多点触碰其实非常好!因为我前面说了,每一个触碰点都会单独经历Begin->Moved->End;所以我们可以新建一个CCArray来记录进入Begin的触碰CCTouch点!
bool SimpleDragZoomLayer::ccTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent){ if (m_pTouches->containsObject(pTouch) == false) { m_pTouches->addObject(pTouch); } ……
然后分别通过m_pTouches的数量来检测是单指操作,还是双指操作!
下面是我的一个实现逻辑,当然你有更好的解决,或者针对我的实现可以帮忙提高下代码的控制用户体验非常欢迎提供反馈~
具体内容请看实现的例子项目,使用的话,可以直接用
//create zoom and drag controller for this layer.
SimpleDragZoomLayer::create(_tiledMap);
把它赋给需要控制的layer即可,当然一般是地图层!
项目源代码:分数有点多~实在抱歉了。尊重版权~谢谢~
http://download.csdn.net/detail/chiuan/5060318