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就对了。

由于是自己摸索出来的,也不知道其他的开发团队是用怎样方式来处理这个问题的。如果哪位小伙伴有更好的处理方案或者觉得以上处理需要优化的点,可以直接提出来。也希望能让更多人少跳一些坑,以此来纪念当初的蛋疼。

相关文章

    本文实践自 RayWenderlich、Ali Hafizji 的文章《...
Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@1...
第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从C...
    Cocos2d-x是一款强大的基于OpenGLES的跨平台游戏开发...
1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《...
   Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试...