首先的是不知不覺的自己快做手機遊戲兩年了。最近空閒了,總結一下之前遇到了各種坑,以及解決方案。首先是在做第一個項目的時候,先說說印象最深刻的也是最蛋疼的事情。在遊戲快要上線的時候,也就是需要接入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就對了。
由於是自己摸索出來的,也不知道其他的開發團隊是用怎樣方式來處理這個問題的。如果哪位小夥伴有更好的處理方案或者覺得以上處理需要優化的點,可以直接提出來。也希望能讓更多人少跳一些坑,以此來紀念當初的蛋疼。