Cocos2d-x 觸摸事件和優(yōu)先級

2018-10-02 09:50 更新

觸摸事件和優(yōu)先級

飛機也登場了,子彈也可以正常發(fā)射了,但是不能動的飛機算神馬回事,坑爹呢?。?!

整個游戲的觸摸事件處理我們把它放在GameLayer中,比較直觀。

1.CCTargetedTouch

我們先看一下CCLayer的聲明:

    class CC_DLL CCLayer : public CCNode, public CCTouchDelegate, public CCAccelerometerDelegate, public CCKeypadDelegate

它是從CCNode繼承來的,同時也繼承了3個硬件相關(guān)接口事件,分別是觸摸事件,加速器事件和鍵盤事件。

所以我們可以直接在CCLayer中進行觸摸事件的處理。

觸摸事件中有兩個類,CCStandradTouch,CCTargetedTouch。前者為多點觸摸,后者為單點觸摸,而系統(tǒng)默認注冊前者分發(fā)事件,我們這里要進行繼續(xù)重載虛函數(shù)registerWithTouchSpatcher,對單點有效。

    //init()中設置可觸摸
    this->setTouchEnabled(true);
    void GameLayer::registerWithTouchDispatcher()
    {
        CCDirector *pDirector=CCDirector::sharedDirector();
        pDirector->getTouchDispatcher()->addTargetedDelegate(this,0,true);
    }

CCStandradTouch這里就不進行討論了。

2.觸摸的回調(diào)函數(shù)

    virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);//觸摸開始調(diào)用
    virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);//觸摸移動調(diào)用
    virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);//觸摸結(jié)束調(diào)用
    virtual void ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent);//一般是系統(tǒng)級調(diào)用,比如觸摸過程中來電之類的

這里我們只要重寫前兩個就夠了。

其中ccTouchBegan返回的是bool值。

A.如果返回true,表示當前層接收觸摸事件,同時允許ccTouchMoved,ccTouchEnded和ccTouchCancelled的調(diào)用。

B.如果返回false,表示當前層不接受觸摸事件,后面的ccTouchMoved等等也就不往下走了。

而ccTouchMoved就是我們進行飛機移動處理的主戰(zhàn)場了。

    //GameLayer.cpp
    bool GameLayer::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)
    {
        return true;//表示當前層接收觸摸事件處理
    }

    void GameLayer::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent)
    {
        if (this->planeLayer->isAlive)//isAlive是AirPlane的一個成員屬性,表示飛機是否還活著
        {
            CCPoint beginPoint=pTouch->locationInView();
            beginPoint=CCDirector::sharedDirector()->convertToGL(beginPoint); //獲取觸摸坐標
            //juggle the area of drag
            CCRect planeRect=this->planeLayer->getChildByTag(AIRPLANE)->boundingBox();//獲取飛機當前位置形狀位置
            planeRect.origin.x-=15;
            planeRect.origin.y-=15;
            planeRect.size.width+=30;
            planeRect.size.height+=30;//允許稍微加大一點觸摸位置,游戲?qū)嶋H需要
            if(CCRect::CCRectContainsPoint(planeRect,
                this->getParent()->convertTouchToNodeSpace(pTouch))==true) //判斷觸摸點是否在飛機范圍內(nèi)
            {
                CCPoint endPoint=pTouch->previousLocationInView();//獲取觸摸的前一個位置
                endPoint=CCDirector::sharedDirector()->convertToGL(endPoint);

                CCPoint offSet =ccpSub(beginPoint,endPoint);//獲取offset
                CCPoint toPoint=ccpAdd(this->planeLayer->getChildByTag(AIRPLANE)->getPosition(),offSet); //獲取真正移動位置
                this->planeLayer->MoveTo(toPoint); //移動飛機
            }
        }
    }
    //PlaneLayer.cpp
    void PlaneLayer::MoveTo(CCPoint location)
    {
        //飛機及游戲狀態(tài)判斷
        if(isAlive && !CCDirector::sharedDirector()->isPaused())
        {
            //進行邊界判斷,不可超出屏幕
            CCPoint actualPoint;
            CCSize winSize=CCDirector::sharedDirector()->getWinSize();
            CCSize planeSize=this->getChildByTag(AIRPLANE)->getContentSize();
            if (location.xwinSize.width-planeSize.width/2)
            {
                location.x=winSize.width-planeSize.width/2;
            }
            if (location.ywinSize.height-planeSize.height/2)
            {
                location.y=winSize.height-planeSize.height/2;
            }
            this->getChildByTag(AIRPLANE)->setPosition(location);
        }
    }

3.觸摸優(yōu)先級和觸摸事件的吞噬

大家看到觸摸事件的分派注冊中,addTargetdDelegate第二個和第三個函參,又是什么意思呢?

A.第二個參數(shù)表示觸摸事件的優(yōu)先級,值越小,優(yōu)先級越高,比如層1的優(yōu)先級是-50,層2的優(yōu)先級是-100,那么層2會先接收并處理觸摸事件,然后才有機會輪到層1來接收處理。

B.第三個參數(shù)表示swallow事件,表示當前層是否吞噬掉這個觸摸,即不往優(yōu)先級更低的層傳送。

要注意的是觸摸事件的觸發(fā)是根據(jù)添加的順序依次觸發(fā)的,后添加的層先捕獲觸摸事件,當然,這是沒有設置事件優(yōu)先級的情況下,若要是定義了事件的優(yōu)先級,則先按照事件的優(yōu)先級依次被觸發(fā),然后根據(jù)添加的順序依次被觸發(fā)。CCMenu的優(yōu)先級是-128,而CCControlButton的優(yōu)先級是0。

好了,這一節(jié)后,我們就可以控制飛機移動并且發(fā)射子彈了,而子彈一旦超出屏幕就會被回收,飛機也不會超出屏幕外。

效果圖


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號