触屏事件:
CCStandardTouchDelegate协议是标准的获得多点触摸的范例,CCTargetedTouchDelegate不用处理触摸点的集合,它是返回单点的。但请注意:CCTargetedTouchDelegate并没有屏蔽多点触摸,而是将多点离散成了单点,同时传递过来了。可以在开始触摸的函数中返回true来实现之后获得的触摸点肯定是自己的。此外,在布景层类CCLayer中可以重写ccTouchesBegan等函数获得触屏信息。
触摸点CCTouch
一般把触摸点的信息放入触点类CCTouch中
locationInView(返回类型->坐标点) :获得点在画布中的位置
previousLocationInView(返回类型->坐标点):之前在画布中的位置
setTouchInfo(返回->空):设置信息,三个参数为ID号、x坐标、y坐标
getID(返回->整形):获得ID号
获得坐标值:
CCPoint point = touch->locationInView();
point = CCDirector->sharedDirector()->convertToGL(point);
单/多点触摸函数:
ccTargetedTouchDelegate将触摸点分发给各个接收的函数,使用ccTouchBegan,并在返回时返回true,可以让这个触点属于
这个函数的所属对象,并且其他对象不再接收该触点,之后再获得的触摸点肯定是它自己的,这样就省去了对多点触摸时的判断
手指移除屏幕或者目标对象的范围不会触发ccTouchCanceled,这种情况下调用的依然是ccTouchEnded函数。事实上,系统中
断通知需要取消触摸时间的时候会调用ccTouchCancelled,这个中断被调用往往是因为如下几种情况:
1)应用程序长时间没有响应或者当前视图从系统的顶层上移除
2)程序进入后台时,有可能是来电中断、电量低中断和部分机型上的home键被按下
3)屏幕关闭和触摸的时候,某种原因导致距离传感器工作,例如脸靠近
4)部分触摸权限覆盖了本应用的触摸权限
加入单点触摸:
void TouchesPerformTest1::onEnter(){
TouchesMainScene::onEnter();
setTouchEnabled(true);
}
std::string TouchesPerformTest1::title(){
return "Targeted touches";
}
void TouchesPerformTest1::registerWithTouchDispatcher(){
CCDirector* pDirector = CCDirector::sharedDirector();
pDirector->getTouchDispatcher()->addTargetDelegate(this,0,true);
}
bool TouchesPerformTest1::ccTouchBegan(CCTouch* touch,CCEvent* event){
numberOfTouchesB++;
return true;
}
void TouchesPerformTest1::ccTouchMoved(CCTouch* touch,CCEvent* event){
numberOfTouchesM++;
}
void TouchesPerformTest1::ccTouchEnded(CCTouch* touch,CCEvent* event){
numberOfTouchesE++;
}
void TouchesPerformTest1::ccTouchCancelled(CCTouch* touch,CCEvent* event){
numberOfTouchesC++;
}
/* addTargetedDelegate函数的第一个参数是加入代理的对象,第二个参数是触摸的优先级。触摸的优先级决定了触摸的分发顺序,触摸分发只和布景层的触摸优先级有关,和布景层的渲染顺序(zOrder)完全没关系。最后一个参数代表是否“吞噬”所有的触摸点,如果在本布景层吞噬掉相应的触摸点,那么比它权限低 的以及CCStandardTouchDelegate标准触摸代理无论是多高的权限全都收不到触摸分发 */
如果非布景层和其子类想要使用触摸,那么继承相应代理即可:
class Paddle : public CCSprite,public CCTargetedTouchDelegate{
PaddleState m_state;
public:
};paddle(void);
virtual ~Paddle(void);
CCRect rect();
bool initWithTexture(CCTexture2D* aTexture);
virtual void onEnter();
virtual void onExit();
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);
vritual void touchDelegateRetain();
virtual void touchDelegateRelease();
static Paddle* paddleWithTexture(CCTexture2D* aTexture);
与布景层CCLayer不同的是,这里需要在onEnter和onExit中注册/注销触摸的代理:
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();
}
加入多点触摸:
void TouchesPerformTest2::onEnter(){
TouchesMainScene::onEnter();
setTouchEnabled(true);
}
std::string TouchesPerformTest2::title(){
return "Standard touches";
}
void TouchesPerformeTest2::registerWithTouchDispatcher(){
CCDirector* pDirector = CCDirector::sharedDirector();
pDirector->getTouchDispatcher()->addStandardDelegate(this,0);
}
void TouchesPerformTest2::ccTouchesBegan(CCSet* touches,CCEvent* event){
numberOfTouchesB += touches->count();
}
void TouchesPerformTest2::ccTouchesMoved(CCSet* touches,CCEvent* event){
numberOfTouchesM += touches->count();
}
void TouchesPerformTest2::ccTouchesEnded(CCSet* touches,CCEvent* event){
numberOfTouchesE += touches->count();
}
void TouchesPerformTest2::ccTouchesCancelled(CCSet* touches,CCEvent* event){
numberOfTouchesC += touches->count();
}
多点触摸的实现步骤和单点触摸类似,只是需要从CCSet里获得触点类CCTouch:
void MutiTouchTestLayer::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent)
{
CCSetIterator iter = pTouches->begin();
for (; iter != pTouches->end(); iter++){
CCTouch* pTouch = (CCTouch*)(*iter);
TouchPoint* pTouchPoint = TouchPoint::touchPointWithParent(this);
CCPoint location = pTouch->getLocation();
pTouchPoint->setTouchPos(location);
pTouchPoint->setTouchColor(s_TouchColors[pTouch->getID()]);
addChild(pTouchPoint);
s_dic.setObject(pTouchPoint, pTouch->getID());
}
}
源相关代码:
class TouchPoint : public CCNode
{
public:
TouchPoint()
{
setShaderProgram(CCShaderCache::sharedShaderCache()->programForKey(kCCShader_PositionTextureColor));
}
virtual void draw()
{
ccDrawColor4B(m_TouchColor.r, m_TouchColor.g, m_TouchColor.b, 255);
glLineWidth(10);
ccDrawLine( ccp(0, m_pTouchPoint.y), ccp(getContentSize().width, m_pTouchPoint.y) );
ccDrawLine( ccp(m_pTouchPoint.x, 0), ccp(m_pTouchPoint.x, getContentSize().height) );
glLineWidth(1);
ccPointSize(30);
ccDrawPoint(m_pTouchPoint);
}
void setTouchPos(const CCPoint& pt)
{
m_pTouchPoint = pt;
}
void setTouchColor(ccColor3B color)
{
m_TouchColor = color;
}
static TouchPoint* touchPointWithParent(CCNode* pParent)
{
TouchPoint* pRet = new TouchPoint();
pRet->setContentSize(pParent->getContentSize());
pRet->setAnchorPoint(ccp(0.0f, 0.0f));
pRet->autorelease();
return pRet;
}
private:
CCPoint m_pTouchPoint;
ccColor3B m_TouchColor;
};
bool MutiTouchTestLayer::init()
{
if (CCLayer::init())
{
setTouchEnabled(true);
return true;
}
return false;
}
static CCDictionary s_dic;
void MutiTouchTestLayer::registerWithTouchDispatcher(void)
{
CCDirector::sharedDirector()->getTouchDispatcher()->addStandardDelegate(this, 0);
}
void MutiTouchTestLayer::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent)
{
CCSetIterator iter = pTouches->begin();
for (; iter != pTouches->end(); iter++)
{
CCTouch* pTouch = (CCTouch*)(*iter);
TouchPoint* pTouchPoint = TouchPoint::touchPointWithParent(this);
CCPoint location = pTouch->getLocation();
pTouchPoint->setTouchPos(location);
pTouchPoint->setTouchColor(s_TouchColors[pTouch->getID()]);
addChild(pTouchPoint);
s_dic.setObject(pTouchPoint, pTouch->getID());
}
}
void MutiTouchTestLayer::ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent)
{
CCSetIterator iter = pTouches->begin();
for (; iter != pTouches->end(); iter++)
{
CCTouch* pTouch = (CCTouch*)(*iter);
TouchPoint* pTP = (TouchPoint*)s_dic.objectForKey(pTouch->getID());
CCPoint location = pTouch->getLocation();
pTP->setTouchPos(location);
}
}
void MutiTouchTestLayer::ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent)
{
CCSetIterator iter = pTouches->begin();
for (; iter != pTouches->end(); iter++)
{
CCTouch* pTouch = (CCTouch*)(*iter);
TouchPoint* pTP = (TouchPoint*)s_dic.objectForKey(pTouch->getID());
removeChild(pTP, true);
s_dic.removeObjectForKey(pTouch->getID());
}
}
void MutiTouchTestLayer::ccTouchesCancelled(CCSet *pTouches, CCEvent *pEvent)
{
ccTouchesEnded(pTouches, pEvent);
}
void MutiTouchTestScene::runThisTest()
{
MutiTouchTestLayer* pLayer = MutiTouchTestLayer::create();
addChild(pLayer, 0);
CCDirector::sharedDirector()->replaceScene(this);
}