cocos2d開發響應android手機home和back的處理優化

  首先的是不知不覺的自己快做手機遊戲兩年了。最近空閒了,總結一下之前遇到了各種坑,以及解決方案。首先是在做第一個項目的時候,先說說印象最深刻的也是最蛋疼的事情。在遊戲快要上線的時候,也就是需要接入sdk的時候,發現了一下很讓人背痛的問題。由於之前沒有考慮到響應android的home 以及back鍵的機制,以至於我們寫的每一個layer都要在back響應事件函數中明確指明返回到具體的哪一個layer。然而這還不是最頭痛的,當我們加入各種計費點的彈出框之後,你就會徹底的凌亂了,被各種複雜的跳轉關係給活生生的弄得蛋碎了一地。

     在那時就想着一定要解決這個問題,後來想出來的解決方案是,建立一個LayerOrderCtrl類,其中裏面是一個隊列來保存當前所用場景中所用需要響應back和home事件的layer,LayerOrderBase這個類定義了handBackPress 和handHomePress兩個函數, 然後讓這些layer都繼承自LayerOrderBase,並各種實現這兩個函數,而實現原理則是利用棧的FILO的原理,讓back事件始終返回到上一個layer中去。而LayerOrderCtrl管理着一個LayerOrderBase的deque代碼如下:

class LayerOrderBase
{
public:
    virtual void handleBackPress()
    {}
    virtual void handleHomePress()
    {}
};

enum class KeyPressType
{
    KPT_HOME,
    KPT_BACK,
};

/**
 *  層級管理組件
 *  維護一個隊列,保證最後一個加入的,在隊列最前端。
 *  用於響應android的back與home按鍵
 */
class LayerOrderCtrl
{
public:
    static LayerOrderCtrl* getInstance();
    
    /**
     *  推入一個新層到隊列最前端
     *
     *  @param lob 需要加入的數據
     */
    void push(LayerOrderBase* lob);
    
    /**
     *  彈出隊列最前端的一項數據
     */
    void pop();
    
    /**
     *  清空整個隊列
     */
    void clear();
    
    /**
     *  刪除隊列中某個數據
     *
     *  @param lob 需要刪除的數據
     */
    void remove(LayerOrderBase* lob);
    
    /**
     *  向隊列前段第一個數據發送一條消息
     *
     *  @param type 消息類型
     */
    void sendMsg(KeyPressType type);
    
protected:
    static LayerOrderCtrl* m_instance;
    
    std::deque<LayerOrderBase*> m_LayerDeque;
private:
    LayerOrderCtrl(){}
    ~LayerOrderCtrl(){}
};

#include "LayerOrderCtrl.h"

LayerOrderCtrl* LayerOrderCtrl::m_instance = nullptr;

LayerOrderCtrl* LayerOrderCtrl::getInstance()
{
    if(m_instance == nullptr)
        m_instance = new LayerOrderCtrl();
    return m_instance;
}

void LayerOrderCtrl::push(LayerOrderBase* lob)
{
    m_LayerDeque.push_front(lob);
}

void LayerOrderCtrl::pop()
{
    m_LayerDeque.pop_front();
}

void LayerOrderCtrl::clear()
{
    m_LayerDeque.clear();
}

void LayerOrderCtrl::remove(LayerOrderBase* lob)
{
    for(auto iter = m_LayerDeque.begin(); iter != m_LayerDeque.end(); iter++)
    {
        if(*iter == lob)
        {
            m_LayerDeque.erase(iter);
            break;
        }
    }
}

void LayerOrderCtrl::sendMsg(KeyPressType type)
{
    if(!m_LayerDeque.empty() && m_LayerDeque.front() != nullptr)
    {
        switch (type)
        {
            case KeyPressType::KPT_HOME :
                m_LayerDeque.front()->handleHomePress();
                break;
                
            case KeyPressType::KPT_BACK:
                m_LayerDeque.front()->handleBackPress();
                break;
                
            default:
                break;
        }
    }
}

這樣做的效果在下一個項目中響應android的back以及home事件得到了很好的應用,而且不用在意具體返回到哪一個layer之類的,反正回到上一個layer就對了。

由於是自己摸索出來的,也不知道其他的開發團隊是用怎樣方式來處理這個問題的。如果哪位小夥伴有更好的處理方案或者覺得以上處理需要優化的點,可以直接提出來。也希望能讓更多人少跳一些坑,以此來紀念當初的蛋疼。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章