当前位置:编程学习 > wap >>

Cocos2d-x学习(三):触屏事件(单点触屏)

cocos2d-x中的触屏事件分为多点触屏和单点触屏,而多点触屏用到的地方并不是很多,所以先主要记录一下单点触屏的用法和基本原理。

 


一般经常用到的触屏的情况有两种:一种是Layer统一接收触屏消息,然后由程序根据需要分发给不同位置的精灵;另一种情况是自定义一个可以接收触屏消息的Sprite,比如类似于Button功能的Sprite,这就需要在定义Sprite的时候就要定义好触屏所触发的操作!

 


下面就两种情况分别记录一下基本用法:

1.Layer接收触屏消息
用法很简单,只需要覆写父类的4个方法(可以根据需要,但是ccTouchBegan()是必须要覆写的,并且其返回值对触屏事件的传递有影响,后面会总结),并在init()方法中将其添加到CCTouchDispacher中,代码如下

[cpp]
<span style="font-size:12px;">class TouchableLayer: public CCLayer  

public: 
     
    virtual bool init(); 
     
    LAYER_NODE_FUNC(TouchableLayer); 
     
    virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);</span> 
<span style="font-size:12px;">class TouchableLayer: public CCLayer
{
public:
   
    virtual bool init();
   
    LAYER_NODE_FUNC(TouchableLayer);
   
    virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);</span>[cpp] view plaincopyprint?<span style="font-size:12px;"> 
    virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent); 
    virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent); 
    virtual void ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent); 
};</span> 
<span style="font-size:12px;">
    virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);
    virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);
    virtual void ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent);
};</span>在Layer的init()中添加如下代码,这个Layer就可以接收到触屏消息了

[cpp]
<span style="font-size:12px;">CCTouchDispatcher::sharedDispatcher()->addTargetedDelegate(this, 0, true);</span> 
<span style="font-size:12px;">CCTouchDispatcher::sharedDispatcher()->addTargetedDelegate(this, 0, true);</span>

如果想通过这种方式判断具体触摸的Sprite或者区域等信息,就需要自己写判断和分发消息的代码了!

2.自定义可以接收触屏消息的Sprite
这种稍微复杂一些,但是还是比较好理解的,首先要先继承CCSprite或者其父类,以满足精灵形状,位置等信息的要求,另外还需要继承触屏事件委托CCTargetedTouchDelegate,CCTargetedTouchDelegate中定义了接收触屏信息的回调虚函数,而这些虚函数,正是我们需要覆写的部分,代码如下

[cpp]
<span style="font-size:12px;">class TouchableSprite: public CCSprite, public CCTargetedTouchDelegate 

     
public: 
    TouchableSprite(); 
    virtual ~TouchableSprite(); 
     
    static TouchableSprite *touchSpriteWithFile(const char *file); 
     
    bool initWithFile(const char *file); 
     
    virtual void onEnter(); 
    virtual void onExit(); 
     
    CCRect rect(); 
    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); 
 
}; 
</span> 
<span style="font-size:12px;">class TouchableSprite: public CCSprite, public CCTargetedTouchDelegate
{
   
public:
    TouchableSprite();
    virtual ~TouchableSprite();
   
    static TouchableSprite *touchSpriteWithFile(const char *file);
   
    bool initWithFile(const char *file);
   
    virtual void onEnter();
    virtual void onExit();
   
    CCRect rect();
    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);

};
</span>重点在于判断自定义Sprite是否被点击,这时就需要得到精灵所在的矩形了,这时又有两种判断方式

(1)得到触屏所在位置,然后根据精灵所在位置的矩形区域和触屏的点判断是否包含,如果包含,则说明触摸到了Sprite。这里写了一个得到精灵当前所在矩形的方法

[cpp]
<span style="font-size:12px;">CCRect TouchableSprite::rect() 

    CCSize size = getContentSize(); 
    CCPoint pos = getPosition(); 
 
    return CCRectMake(pos.x - size.width / 2, pos.y - size.height / 2, size.width, size.height); 
}</span> 
<span style="font-size:12px;">CCRect TouchableSprite::rect()
{
    CCSize size = getContentSize();
    CCPoint pos = getPosition();

    return CCRectMake(pos.x - size.width / 2, pos.y - size.height / 2, size.width, size.height);
}</span>然后在每次点击的时候都需要将当前触屏位置转换为GL坐标的位置,然后和Sprite所在矩形做包含判断

[cpp]
<span style="font-size:12px;">bool TouchableSprite::containsTouchLocation(cocos2d::CCTouch *touch) 

    CCPoint touchPoint = touch->locationInView(touch->view()); 
    touchPoint = CCDirector::sharedDirector()->convertToGL(touchPoint); 
     
    return CCRect::CCRectContainsPoint(rect(), touchPoint); 
}</span> 
<span style="font-size:12px;">bool TouchableSprite::containsTouchLocation(cocos2d::CCTouch *touch)
{
    CCPoint touchPoint = touch->locationInView(touch->view());
    touchPoint = CCDirector::sharedDirector()->convertToGL(touchPoint);
   
    return CCRect::CCRectContainsPoint(rect(), touchPoint);
}</span>
(2)其实cocos2d为我们提供了一种相对简单的方法,但是原理类似,调用CCNode中定义的convertTouchToNodeSpaceAR()方法,将触屏点转化为相对于结点的相对坐标

(ps:由于默认anchor点是中点,所以每一个Sprite上的相对坐标系是从(-width / 2, -height / 2)为左上角点坐标),所以上面的两个方法需要修改一下 www.zzzyk.com

[cpp]
<span style="font-size:12px;">CCRect TouchableSprite::rect() 

    CCSize size = getTexture()->getContentSize(); 
 
    return CCRectMake(-size.width / 2, -size.height / 2, size.width, size.height); 
}</span> 
<span style=

补充:移动开发 , 其他 ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,