【cocos2d-x游戏开发】 从零单排之(三)

这篇文章主要介绍touch事件机制,还会涉及到一些的介绍Cocos2d-x的内存回收相关内容。

一、触摸事件

简单介绍一下Touch事件流程:玩家触摸到设备屏幕后,引擎会把触摸事件派发给注册了事件监听的相应代理,触摸的具体信息会以参数的形式传递给相应回调函数。
GameEngin-> EventDispatcher -> ??->onTouchXXX

TouchEvent(触摸事件)分为2种 :EventListenerTouchAllAtOnce(多点触摸) 和  EventListenerTouchOneByOne (单点触摸)。
以单点触摸为例,创建一个Touch事件后,要给 touch->onTouchBegan   onTouchCancelled onTouchEnded onTouchMoved 赋值相应的回调,这4个回调分别代表了
onTouchBegan   开始接触屏幕
onTouchCancelled   事件被取消(比如程序切到后台)
onTouchEnded  触摸事件结束,手指离开屏幕
onTouchMoved 手指在屏幕上滑动

这4个回调方法里,除了第一个 onTouchBegan   的返回值是bool,其他都是void。那么这个bool有什么用呢? 看一下CCEventDispatcher的源码(CCEventDispatcher.cpp),不难发现, 当开始触摸事件返回true时,之后的触摸结束、触摸移动等事件才能触发,反之,如果TouchBegan返回false,后面的流程不会被触发。
下面贴出给node添加Touch事件的流程
<span style="white-space:pre">		</span>//添加点击监听(单点触摸)
		EventListenerTouchOneByOne* tevent = EventListenerTouchOneByOne::create();
		tevent->setSwallowTouches(true);
		tevent->onTouchBegan = [&](Touch* touch, Event*){
				for(auto key : m_clickDelegates)
				{
					key.second(touch);
				}
				return false;
			};
		tevent->onTouchCancelled = [&](Touch*, Event*){
				
			};
		tevent->onTouchEnded = [&](Touch*, Event*){
				
			};
		tevent->onTouchMoved = [&](Touch*, Event*){
				
			};
		Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(tevent,this);
setSwallowTouches  代表是否阻止当前事件向下一层级派发。

二、cocos2d::Map std::map (这里用大写的Map代表Cocosd中的,小写的map代表标准库函数中的)

cocos2d::Map和std::map功能基本一样,不同的是,Map沿用了cocos2dx的内存回收机制,当添加一个value到Map中时,value.retain()会被调用,移除后,value.release()会被调用,这样,我们就不用手动的去处理map内部引用计数了,但为了使用这个便利,Map<k,v>中的v 必须是 Ref* 类型 !。 这样,如果想用Ref* 做key,而value是一个 std::function<void(Touch*)>类型,就只能使用标准库函数了,但这样就要自己处理Map内部Ref* 类型的引用计数。
之前一直相当然的认为对std::map遍历的时候,是直接遍历所有的value,但结果遍历的类型是 std::pair<k,v>  。

下面看一下单点触摸层简单实现
class LayerTouch:public cocos2d::Layer
{
public:
	LayerTouch();
	~LayerTouch();
	virtual bool init();
	static LayerTouch* create();
	//添加当前回调事件到点击事件回调map中
	void addClickDelegate(cocos2d::Ref*,std::function
    
    
     
     );
private:
	//点击事件回调字典
	std::map
     
     
      
      
       
       > m_clickDelegates;
};
#include "LayerTouch.h"
USING_NS_CC;
LayerTouch::LayerTouch():m_clickDelegates(std::map
       
       
        
        
          >()) { } LayerTouch::~LayerTouch() { for(std::map 
          
          
            >::iterator iter = m_clickDelegates.begin();iter != m_clickDelegates.end();iter++) { iter->first->release(); } m_clickDelegates.clear(); } void LayerTouch::addClickDelegate(cocos2d::Ref* clickDelegate,std::function 
           
             callback) { m_clickDelegates[clickDelegate] = callback; clickDelegate->retain(); } bool LayerTouch::init() { if(Layer::init()) { //添加点击监听(单点触摸) EventListenerTouchOneByOne* tevent = EventListenerTouchOneByOne::create(); tevent->setSwallowTouches(true); tevent->onTouchBegan = [&](Touch* touch, Event*){ for(auto key : m_clickDelegates) { key.second(touch); } //true 会继续监听后面的touch move,touch end等事件,false则不会 return false; }; tevent->onTouchCancelled = [&](Touch*, Event*){ }; tevent->onTouchEnded = [&](Touch*, Event*){ }; tevent->onTouchMoved = [&](Touch*, Event*){ }; Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(tevent,this); return true; } return false; } LayerTouch* LayerTouch::create() { LayerTouch* tlayer = new LayerTouch(); if(tlayer && tlayer->init()) { tlayer->autorelease(); return tlayer; }else { CC_SAFE_RELEASE(tlayer); } return nullptr; } 
            
           
          
        
       
       
      
      
     
     
    
    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值