cocos2dx 2.2 之触摸事件
要使精灵能够接收到触摸事件,无非要做三件事。
注册触摸事件;
接收触摸事件;
处理触摸事件。
下面就从这三点出发,来了解一下精灵如何响应触摸事件。
1.注册触摸事件
精灵类Poker继承Sprite和CCTargetedTouchDelegate,并重写CCTargetedTouchDelegate的三个函数ccTouchBegan,ccTouchMoved,ccTouchEnded
同时加入辅助函数rect()和containTouchPoint(CCTouch* touch)用于后面的判断。
poker.h文件:
[cpp] view plaincopyprint?
- class Poker : public CCSprite ,public CCTargetedTouchDelegate
- {
- PokerState m_state;
- public:
- Poker(void);
- CCRect rect();
- virtual void onEnter();
- virtual void onExit();
- virtual ~Poker(void);
- boolean containTouchPoint(CCTouch* touch);
- virtual bool ccTouchBegan(CCTouch *touch ,CCEvent *event);
- virtual void ccTouchMoved(CCTouch *touch ,CCEvent *event);
- virtual void ccTouchEnded(CCTouch *touch ,CCEvent *event);
- };
poker.cpp文件:
这里需要再poker.cpp中添加具体的注册行为,onEnter和onExit函数分别是精灵创建和销毁时调用,因为可以在这两个函数中添加注册和销毁注册。
[cpp] view plaincopyprint?
- //CCNode进入场景时调用
- void Poker::onEnter()
- {
- CCDirector* pDirector = CCDirector::sharedDirector();
- pDirector->getTouchDispatcher()->addTargetedDelegate(this, 0, true);
- CCSprite::onEnter();
- }
- //CCNode退出场景时调用
- void Poker::onExit()
- {
- CCDirector* pDirector = CCDirector::sharedDirector();
- pDirector->getTouchDispatcher()->removeDelegate(this);
- CCSprite::onExit();
- }
以上,我们的触摸事件注册流程就完成了。
2.接收触摸事件
接收触摸事件,实际上就是重写CCTargetedTouchDelegate的三个函数ccTouchBegan,ccTouchMoved,ccTouchEnded。
[cpp] view plaincopyprint?
- bool Poker::ccTouchBegan(CCTouch *touch ,CCEvent *event)
- {
- CCLog("Poker ccTouchBegan ");
- return false;
- }
- void Poker::ccTouchMoved(CCTouch *touch ,CCEvent *event)
- {
- CCLog("Poker ccTouchMoved ");
- }
- void Poker::ccTouchEnded(CCTouch *touch ,CCEvent *event)
- {
- CCLog("Poker ccTouchEnded ");
- }
如此,接收流程已经完成,无意外的话,运行可以看到打印日志了。
3.处理触摸事件
首先要获取当前精灵所在的矩形。
也即是CCRect Poker::rect()需要做的事情。
请注意,这里获取的方式的前提是,精灵使用系统默认的锚点,也即是精灵的正中央,如果改变过精灵的锚点(setAnchorPoint),那么就需要改变计算方法了。
[cpp] view plaincopyprint?
- CCRect Poker::rect()
- {
- CCSize size = getTexture()->getContentSize();
- return CCRectMake(-size.width / 2 ,-size.height / 2, size.width ,size.height);
- }
如果将当前精灵也看做一个坐标系,若精灵的长为100,宽为100,那么获取的矩形应该是x = -50 , y = -50 ,width = 100 ,height = 100
其次,将触摸事件的点转化为当前精灵内部坐标系的点。
(可能不是很好理解,但是我们每一个继承自CCNode的结点都可以看做一个坐标系)
[cpp] view plaincopyprint?
- boolean Poker::containTouchPoint(CCTouch* touch)
- {
- return rect().containsPoint(convertTouchToNodeSpaceAR(touch));
- }
在CCSprite内部使用convertTouchToNodeSpaceAR函数就可以将当前触摸点转化成精灵内部坐标系的点。
最后,判断触摸事件,并处理。
[cpp] view plaincopyprint?
- bool Poker::ccTouchBegan(CCTouch *touch ,CCEvent *event)
- {
- int x = getPositionX();
- int y = getPositionY();
- if (containTouchPoint(touch))
- {
- setPosition(ccp(x , y + 30));
- }
- CCLog("Poker ccTouchBegan ");
- return false;
- }
如果发现当前触摸点在CCSprite的内部,则将当前CCSprite的Y坐标上移30个像素。