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

2018-10-02 09:50 更新

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

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

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

1.CCTargetedTouch

我們先看一下CCLayer的聲明:

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

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

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

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

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

CCStandradTouch這里就不進(jìn)行討論了。

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

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

這里我們只要重寫前兩個(gè)就夠了。

其中ccTouchBegan返回的是bool值。

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

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

而ccTouchMoved就是我們進(jìn)行飛機(jī)移動(dòng)處理的主戰(zhàn)場(chǎng)了。

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

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

                CCPoint offSet =ccpSub(beginPoint,endPoint);//獲取offset
                CCPoint toPoint=ccpAdd(this->planeLayer->getChildByTag(AIRPLANE)->getPosition(),offSet); //獲取真正移動(dòng)位置
                this->planeLayer->MoveTo(toPoint); //移動(dòng)飛機(jī)
            }
        }
    }
    //PlaneLayer.cpp
    void PlaneLayer::MoveTo(CCPoint location)
    {
        //飛機(jī)及游戲狀態(tài)判斷
        if(isAlive && !CCDirector::sharedDirector()->isPaused())
        {
            //進(jìn)行邊界判斷,不可超出屏幕
            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)先級(jí)和觸摸事件的吞噬

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

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

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

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

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

效果圖


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

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)