Cocos2dx 实现CCNode节点的触摸

本文介绍如何在Cocos2d-x中利用CCNode和CCTouchDelegate实现单点及多点触摸效果,包括触摸事件的注册、响应函数定义及坐标处理技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

当CCNode继承于CCTouchDelegate后,可以实现触摸效果,做法可以模仿CCLayer。

一、单点触摸

1.在.h文件中继承于CCTouchDelegate   e.g class MyNode : public CCNode, public CCTouchDelegate{};

2.在.h中定义单点触摸响应函数 

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);

3.注册一个屏幕事件的委托,来监听用户触屏事件

可以写在onEnter中,CCTouchDispatcher* pDispatcher = CCDirector::sharedDirector()->getTouchDispatcher();

pDispatcher->addTargetedDelegate(this,0,true);

如果CCNode使用了CCTouchDelegate接口,并且注册了触屏委托,那么当用户触摸屏幕后,Cocosd-x会根据当前设备拦截到此事件,并开始遍历Dispatcher的列表,依次对注册过的CCNode进行响应。

4.移除委托

可以在onExit中对触屏委托进行移除,CCTouchDispatcher* pDispatcher =CCDirector::sharedDirector()->getTouchDispatcher();

    pDispatcher->removeDelegate(this);

如果想写的更加完善,可以参考CCLayer中的

registerWithTouchDispatcher()、virtual bool isTouchEnabled()、virtual void setTouchEnabled(bool value);等函数

注意:如果把注册和移除分别写在了构造和析构中,则子类继承后,删除子类的时候,父类的触摸不会消失。所以会出问题。


二、多点触摸

多点触摸与单点触摸类似,第二步定义

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);

第三步pDispatcher->addStandardDelegate(this,0);


如果是继承于CCLayer的类,则需要使用setTouchEnabled(true)开启触摸,并且最好重写registerWithTouchDispatcher函数,在此函数中加载触摸事件代理,在onExit中移除代理。


注意,在节点的触摸效果实现的时候,getDelta获得的是屏幕下的坐标,所以如果在节点中直接使用可能导致不理想的效果。

建议如果在节点中想要进行Node的移动,则需要自己定义临时的坐标变量。

1.在ccTouchBegan的时候对临时变量进行复制,记录点击的坐标(转换过得)。因为pTouch->getLocation()获得的时屏幕下的坐标。

2.在ccTouchMoved中计算坐标差,新坐标(转换过得)减去记录的临时坐标。  然后设置想要移动的坐标setPosition(ccpAdd(新坐标,坐标差)); 

如果直接设置想要移动的节点的坐标为新坐标,则第一次移动的时候体验不好,会有突然过去的感觉。

3.在ccTouchMoved结束的时候,更新临时坐标为当前坐标。

举例:

bool TaskTwo::ccTouchBegan(CCTouch* pTouch,CCEvent* pEvent)

{

    CCLOG("Task2 Touched!");

    //获取点击位置--屏幕下的坐标

    CCPoint point = pTouch->getLocation();

    //转换为拼图下的坐标

    CCPoint converNodePoint = m_spNum->convertToNodeSpace(point);

    //记录点击开始的时候的坐标

    posTmp = converNodePoint;

}

void TaskTwo::ccTouchMoved(CCTouch* pTouch,CCEvent* pEvent)

{

//将点击坐标转换为拼图坐标

    CCPoint converNodePoint =m_spNum->convertTouchToNodeSpace(pTouch);  

    //计算当前坐标与开始点击的时候坐标的差,效果和ccTouchBegan中的转换一样

      CCPoint offX =ccpSub(converNodePoint,posTmp);

     //设置当前坐标

    chip->setPosition(ccpAdd(chip->getPosition() ,offX));//这里不要写成chip->setPosition(ccpAdd(converNodePoint ,offX));

//更新临时坐标为当前坐标

    posTmp = converNodePoint;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值