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