cocos2dx触摸

cocos2d-x一般把触摸点的信息封装成触点类CCTouch中 引擎专门提供了一个负责分发用户操作的信息类 CCTouchDispatcher 作用就是响应对象分发CCTouch对象

CCTouchDispatcher主要派生的有三个类 CCLayer   CCTargetedTouchDelegate  CCStandardTouchDelegate

CCTouchDispatcher主要成员函数:

addTargetedDelegate(CCTargetedTouchDelegate* pDelegate, int nPriority,bool bSwallowsTouches);//主要是将CCTouchDispatcher的对象添加到分发器中

addStandardDelegates(CCTargetedTouchDelegate* pDelegate, int nPriority);

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)   


Summary:实际开发中 需要我们触摸的 一种是布景层 一种是非布景层

第一种是布景层的很简单 cocos2d-x已经帮我们封装好了一些功能 就是在初始化函数中setTouchEnabled 然后重写registerWithTouchDispatcher ccTouchBegan ccTouchMoved ccTouchEnded ccTouchCancelled函数  其中在registerWithTouchDispatcher函数中通过导演类过的触发类 并调用addTargetedDelegate或者addStandardDelegates函数

第二种不是布景层 其实不仅仅只是布景层具有触摸事件机制 每一个CCNode对象都可以 只是cocos2d-x把层现成提供了这样的功能 在这里你需要触发的对象不再是一个层而是一张纹理或者其他对象 就像菜单按钮一样 非布景层想要使用触摸 只要继承相关代理即可

class Paddle : public CCSprite, public CCTargetedTouchDelegate

{

public:
    Paddle(void);
    virtual ~Paddle(void);


    CCRect rect();
    bool initWithTexture(CCTexture2D* aTexture);
    virtual void onEnter();//初始化函数 利用导演类注册代理函数
    virtual void onExit();//这里不像CCLayer 我们需要手动注销代理函数
    bool containsTouchLocation(CCTouch* touch);
    virtual bool ccTouchBegan(CCTouch* touch, CCEvent* event);//重载这些回调函数
    virtual void ccTouchMoved(CCTouch* touch, CCEvent* event);
    virtual void ccTouchEnded(CCTouch* touch, CCEvent* event);
    virtual CCObject* copyWithZone(CCZone *pZone);


    virtual void touchDelegateRetain();
    virtual void touchDelegateRelease();


}


void Paddle::onEnter()
{
    CCDirector* pDirector = CCDirector::sharedDirector();
    pDirector->getTouchDispatcher()->addTargetedDelegate(this, 0, true);
    CCSprite::onEnter();
}

void Paddle::onExit()
{
    CCDirector* pDirector = CCDirector::sharedDirector();
    pDirector->getTouchDispatcher()->removeDelegate(this);
    CCSprite::onExit();
}    


Summary:在实际开发中 一种方式 我们直接创建一个层 实现接口 注册 然后重载回调函数 在重载回调函数 然后判断触摸点的CCPoint和纹理->getpostion得到的CCPoint相互比较从而得到用户现在触摸点是否在纹理的区域内 实际上cocos2d-x的底层也是这么判断的 相信很多windows程序员对这一点很熟悉 但是这种方法似乎只适合一个场景中只有一个需要判断的纹理你(比如前微信飞机大战中 只需要触摸自己的飞机就OK)  如果太多 每一次触摸你既要遍历得到每一个纹理的位置 然后判断 得到不同的响应 显得很繁琐而且最大的缺点 就是判断的方法并不是很精准 因为两个位置的比较 毕竟是我们认为去判断的 比如一个圆形的纹理图片 但是我们只能按照矩形区域来判断 如果不是自己计算很精准 会带来很大的误差

所以我们需要第二种方法 让程序员从繁琐的CCPoint计算中解脱出来 就是需要响应触摸事件纹理继承相关代理 就如同上述代码所示 这样计算的任务就交给cocos2d-x类完成 我们只需要完成一些回调函数的逻辑即可 一方面精准了 另一方面可以很简洁



cocos2d-x两种触摸事件:

1,带目标的触摸事件CCTargetedTouchDelegate:实际上就是单点触摸事件

 virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)       //触摸开始 返回true可以使得触摸点属于该函数的目标对象 该点的变化只会影响该目标函数的调用 不会影响其他对象 

 virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent)       处理Touch Move 事件

virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent)        处理用户放开事件

 virtual void ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent)   处理Touch被打断事件.

为了使一个对象接受带目标的触摸事件 主要有一下四个步骤:

1,对象需要实现CCTargetedTouchDelegate提供的接口

2,使用addTargetedDelegate把自己注册给触摸事件分发器 这里需要注意的是 这里的最后一个参数是一个bool类型的变量 当设置为true的时候会产生吞噬效果 就是所有优先级比自己低的接受对象都无法接受到触摸事件

3,重载事件回调函数 处理触摸事件 这里需要注意的是 在触摸开始事件的函数里 返回值true以捕捉事件

4,当不再需要接受触摸事件的时候,使用removeDelegate方法来注销触摸事件接受





2,标准触摸事件CCStandardTouchDelegate:实际上就是多点触摸事件

CCStandardTouchDelegate包含四个回调函数,分别如下:

     virtual void ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent)   处理用户按下事件

     virtual void ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent)   处理Touch Move 事件

    virtual void ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent)    处理用户放开事件

    virtual void ccTouchesCancelled(CCSet *pTouches, CCEvent *pEvent)  处理Touch被打断事件,如来电话了。

为了使一个对象接受标准触摸事件 主要有一下四个步骤:

1,对象需要实现CCStandardTouchDelegate提供的接口

2,使用addStandardDelegate把自己注册给触摸事件分发器

3,重载事件回调函数 处理触摸事件

4,当不再需要接受触摸事件的时候,使用removeDelegate方法来注销触摸事件接受


Summary:研究过cocos2d-x的源代码之后 发现他们的做法是 首先创建一个主游戏的场景 然后创建需要显示在这个场景中各种层 其中需要实现触摸事件的层注册之后 在运行这个场景中 当有触摸事件发生的时候 就会触发每一个层中的回调函数 但是一般的做法层只是负责接收触摸事件 并把触摸事件分发给代理 然后由代理来完成触摸事件 

使用代理设计模式 可以解除触摸层和实际处理事件的精灵层的耦合 这样的好处是 能有效的分离触摸手势的识别和处理事件两个部分 使代码结构清晰


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值