首先的是不知不觉的自己快做手机游戏两年了。最近空闲了,总结一下之前遇到了各种坑,以及解决方案。首先是在做第一个项目的时候,先说说印象最深刻的也是最蛋疼的事情。在游戏快要上线的时候,也就是需要接入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就对了。
由于是自己摸索出来的,也不知道其他的开发团队是用怎样方式来处理这个问题的。如果哪位小伙伴有更好的处理方案或者觉得以上处理需要优化的点,可以直接提出来。也希望能让更多人少跳一些坑,以此来纪念当初的蛋疼。