鍍金池/ 教程/ Java/ 觸摸事件和優(yōu)先級
游戲暫停和觸摸屏蔽
游戲場景過渡
碰撞檢測
跨平臺移植和廣告植入
批次渲染
觸摸事件和優(yōu)先級
背景音樂和音效
別急,先處理好CCScene和CCLayer的關系
自定義敵機精靈
UFO層特殊道具
主角的登場和幀動畫
引擎坐標系,錨點和背景滾動
分數(shù)的本地存儲
子彈層的處理
搞個飛機來玩玩

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

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

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

1.CCTargetedTouch

我們先看一下CCLayer的聲明:

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

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

所以我們可以直接在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.觸摸的回調函數(shù)

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

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

其中ccTouchBegan返回的是bool值。

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

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;//允許稍微加大一點觸摸位置,游戲實際需要
            if(CCRect::CCRectContainsPoint(planeRect,
                this->getParent()->convertTouchToNodeSpace(pTouch))==true) //判斷觸摸點是否在飛機范圍內
            {
                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ā)是根據添加的順序依次觸發(fā)的,后添加的層先捕獲觸摸事件,當然,這是沒有設置事件優(yōu)先級的情況下,若要是定義了事件的優(yōu)先級,則先按照事件的優(yōu)先級依次被觸發(fā),然后根據添加的順序依次被觸發(fā)。CCMenu的優(yōu)先級是-128,而CCControlButton的優(yōu)先級是0。

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

效果圖

http://wiki.jikexueyuan.com/project/cocos2d-x-getting-real/images/6.1.jpeg" alt="" />