当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;
}