Cocos2d-x 触屏事件解析

本文介绍了Cocos2d-x游戏引擎中触屏事件的处理机制,包括CCTouch、CCTouchDelegate、CCTouchHandler和CCTouchDispatch类的作用,并通过分析AppDelegate中的设置和事件回调函数,说明如何自定义带触摸事件的CCSprite进行响应操作。
摘要由CSDN通过智能技术生成

        触屏事件是游戏的一个很重要的部分,没有了触屏,游戏就不叫游戏。而在Cocos2d-x中触屏事件是如何处理的呢?下面一起来学习学习。

一、首先,了解一下触摸相关的类:


1、CCTouch:封装触摸点,可以返回基于OpenGL或屏幕的点。


2、CCTouchDelegate:触摸事件委托,系统捕捉到事件后交由它或者它的子类处理,所以我们在处理触屏事件时需要继承此类。封装了下面这些函数:

virtual void ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent); 
virtual void ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent); 
virtual void ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent); 
virtual void ccTouchesCancelled(CCSet *pTouches, CCEvent *pEvent); 
  
virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent); 
virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent); 
virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent); 
virtual void ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent);
CCLayer、CCTargetedTouchDelegate(单点触摸)、CCStandardTouchDelegate(多点触摸)都继承此类。


3、CCTouchDispatch:实现触摸事件的分发,封装下面两个函数:

void addStandardDelegate(CCTouchDelegate *pDelegate, int nPriority);
void addTargetedDelegate(CCTouchDelegate *pDelegate, int nPriority, bool bSwallowsTouches);
可以把CCTargetedTouchDelegate和CCStandardTouchDelegate添加到分发列表中。


4、CCTouchHandler:封装了CCTouchDelegate和其对应的优先级,优先级越高,分发的时候就越容易获得事件的处理权。CCStandardTouchHandler和CCTargetedTouchHandler都继承于CCTouchHandler。


说那么多大家都会头晕,那就简单整理一下吧。CCTouch封装了触摸点,CCTouchDelegate是触摸事件委托,CCTouchHandler是封装CCTouchDelegate和其对应的优先级,而CCTouchDispatch是将触摸处理器分发到分发事件,根据优先级来调用。下面重点分析CCTouchDispatch。

/**
CCTouchDispatcher是个单例,程序刚启动时,导演类会将其设为EAGLView触摸代理,当玩家有触摸操作时,系统会自动调用它的对应方法。
CCLayer通过registerWithTouchDispatcher方法将自己注册到CCTouchDispatcher单例中,CCTouchDispatcher检测到触摸信息后,
会在注册队列中遍历这些对象,调用它们的响应方法,使它们可以响应触摸事件.
 */
class CC_DLL CCTouchDispatcher : public CCObject, public EGLTouchDelegate
{
public:
    /**
     * @lua NA
     */
    ~CCTouchDispatcher();
    /**
     * @lua NA
     */
    bool init(void);
    /**
     * @lua NA
     */
    CCTouchDispatcher()
        : m_pTargetedHandlers(NULL)
        , m_pStandardHandlers(NULL)
        , m_pHandlersToAdd(NULL)
        , m_pHandlersToRemove(NULL)
        
    {}

public:
    /** Whether or not the events are going to be dispatched. Default: true */
    bool isDispatchEvents(void);
    void setDispatchEvents(bool bDispatchEvents);

    /** Adds a standard touch delegate to the dispatcher's list.
     * See StandardTouchDelegate description.
     * IMPORTANT: The delegate will be retained.
     * @lua NA
     */
    void addStandardDelegate(CCTouchDelegate *pDelegate, int nPriority);

    /** Adds a targeted touch delegate to the dispatcher's list.
     * See TargetedTouchDelegate description.
     * IMPORTANT: The delegate will be retained.
     * @lua NA
     */
    void addTargetedDelegate(CCTouchDelegate *pDelegate, int nPriority, bool bSwallowsTouches);

    /** Removes a touch delegate.
     * The delegate will be released
     * @lua NA
     */
    void removeDelegate(CCTouchDelegate *pDelegate);

    /** Removes all touch delegates, releasing all the delegates 
     * @lua NA
     */
    void removeAllDelegates(void);

    /** Changes the priority of a previously added delegate. The lower the number,
     * the higher the priority 
     * @lua NA
     */
    void setPriority(int nPriority, CCTouchDelegate *pDelegate);
    /**
     * @lua NA
     */
    void touches(CCSet *pTouches, CCEvent *pEvent, unsigned int uIndex);
    /**
     * @lua NA
     */
    virtual void touchesBegan(CCSet* touches, CCEvent* pEvent);
    /**
     * @lua NA
     */
    virtual void touchesMoved(CCSet* touches, CCEvent* pEvent);
    /**
     * @lua NA
     */
    virtual void touchesEnded(CCSet* touches, CCEvent* pEvent);
    /**
     * @lua NA
     */
    virtual void touchesCancelled(CCSet* touches, CCEvent* pEvent);

public:
    /**
     * @lua NA
     */
    CCTouchHandler* findHandler(CCTouchDelegate *pDelegate);
protected:
    void forceRemoveDelegate(CCTouchDelegate *pDelegate);
    void forceAddHandler(CCTouchHandler *pHandler, CCArray* pArray);
    void forceRemoveAllDelegates(void);
    void rearrangeHandlers(CCArray* pArray);
    CCTouchHandler* findHandler(CCArray* pArray, CCTouchDelegate *pDelegate);

protected:
	// 目标注册队列,作用和m_pStandardHandlers大体相同,唯一区别就是m_pTargetedHandlers可以吞噬自身响应的事件,以阻止
	// 信息继续向下传递,而m_pStandardHandlers没有此功能。CCMenu就是向该队列注册的。
    CCArray* m_pTargetedHandlers;
	// 标准注册队列,当CCLayer对象调用registerWithTouchDispatcher方法时,会将其添加到该数组中,所有该数组中的对象在
	// 玩家触摸屏幕时都会被调用自身的相关方法:ccTouchesBegan、ccTouchesMoved、ccTouchEnded
    CCArray* m_pStandardHandlers;

	// 是否被锁定,当玩家做了触摸操作,CCTouchDispatcher开始遍历注册队列时,该变量会被设置为YES,此时是不能向队列中
	// 添加新的对象,或者从队列中删除对象的。只有当遍历结束,m_bLocked被置回NO后才可以添加或者删除。如果在锁定过程中
	// 执行了这两种操作,那么操作对象会被放入对应的临时队列中,解锁后再把它们同步到注册队列中。
    bool m_bLocked;
	// 是否有等待添加的对象,当CCTouchDispatcher被锁定时,如果有新的对象要注册进来则会被添加进一个临时队列,该队列的
	// 所有成员都是待注册对象,如果队列不为空,m_bToAdd就会被设为YES,那么当锁定解除后,就会把该队列所有成员全部移入
	// standardHandlers或targetedHandlers(它会根据对象的类型自行区分),操作完成后清空临时队列,m_bToAdd设为NO
    bool m_bToAdd;
	// 是否有等待删除的对象,同添加一样,在CCTouchDispatcher被锁定时,需要删除的对象会被放入另一个临时队列,该队列的成员都是等待注销的,
	// 如果队列不为空,m_bToRemove就会被值为YES,锁定解除后再将队列成员依此从注册队列中删除(具体哪个队列会自动判断),
	// 操作完成后清空临时队列,m_bToRemove置回NO。
    bool m_bToRemove;
	// 存放等待注册对象的队列
    CCArray* m_pHandlersToAdd;
	// 存放等待注销对象的队列
    struct _ccCArray *m_pHandlersToRemove;
	// 是否要清空注册队列,同m_bToRemove一样,清空队列同样需要等到解锁后才能执行,这个变量就是标记是否需要清空的。
    bool m_bToQuit;
	// 有触摸操作时,是否遍历注册队列,默认一直是YES
    bool m_bDispatchEvents;

    // 4, 1 for each type of event
	// 一个长度为ccTouchMax=4的结构体队列,每个成员都是一个ccTouchHandlerHelperData结构体,用来存储CCTOUCHBEGAN,CCTOUCHMOVED,
	// CCTOUCHENDED和CCTOUCHCANCELLED四中触摸事件的调用方法。
    struct ccTouchHandlerHelperData m_sHandlerHelperData[ccTouchMax];
};

// end of input group
/// @}

NS_CC_END

#endif // __TOUCH_DISPATCHER_CCTOUCH_DISPATCHER_H__

static int less(const CCObject* p1, const CCObject* p2)
{
    return ((CCTouchHandler*)p1)->getPriority() < ((CCTouchHandler*)p2)->getPriority();
}

bool CCTouchDispatcher::isDispatchEvents(void)
{
    return m_bDispatchEvents;
}

void CCTouchDispatcher::setDispatchEvents(bool bDispatchEvents)
{
    m_bDispatchEvents = bDispatchEvents;
}

/*
+(id) allocWithZone:(CCZone *)zone
{
    @synchronized(self) {
        CCAssert(sharedDispatcher == nil, @"Attempted to allocate a second instance of a singleton.");
        return [super allocWithZone:zone];
    }
    return nil; // on subs
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值