1.简介
最近在做个小的示例项目,确定后打算用cocos2dx框架来做UI部分,毕竟它易于使用还跨平台,像我这样几乎完全没有cocos2dx基础的童鞋,也能快速上手。在开发过程中,我想像在桌面应用中那样,弹出一个窗口并给出一些文本提示。无奈好像cocos2dx并没有给出现成可用的东西,只能自己琢磨实现了。考虑过后,打算通过Layer类来构建一个子类,然后在Scene中去显示该Layer,从而模拟出“窗口”的效果。我查阅了一些资料发现,网上有很多类似的实现代码,但他们大多已经过时,因这两年cocos2dx的版本变化好像挺大。
2.问题描述
按照上述的思路构建子类测试后发现,监听的事件不会被“阻隔”,例如:我们在Scene中监听了鼠标和键盘,然后在Scene中去添加了该Layer,并在该Layer中也监听了鼠标点击事件,当我们在该Layer中点击鼠标时,Scene中也会触发该事件。这就导致了一些奇怪的现象,和预期不符合。本文将试着简介如何用一种足够简单的方法,构建这样一个“模态对话框类”并解决包含事件不“阻隔”在内的几乎所有问题。
在开始前,先简要说明一下环境。本次实验编写于Linux平台,并提供了源码的Github地址【Download Source】。因实验于PC平台,我在示例所监听的都是鼠标和键盘事件,对于移动平台的触摸事件未做任何测试,但理论上也是可行的,具体请读者自测和变更,以适应特定的场景。
3.代码实现
首先,给出派生类的头文件。
#ifndef MYGAME_POPUPLAYER_H
#define MYGAME_POPUPLAYER_H
#include "cocos2d.h"
USING_NS_CC;
class PopupLayer:public cocos2d::Layer
{
public:
PopupLayer();
virtual ~PopupLayer();
private:
std::string backgroundImage;
EventListenerMouse *listenerMouse;
public:
virtual bool init() override;
CREATE_FUNC(PopupLayer);
static PopupLayer* create(const std::string backgroundImage);
bool setBackgroundImage(const std::string &backgroundImage);
void okMenuItemCallback(Ref *pSender);
void cancelMenuItemCallback(Ref *pSender);
/**
* Event callback that is invoked every time when Node enters the 'stage'.
* If the Node enters the 'stage' with a transition, this event is called when the transition starts.
* During onEnter you can't access a "sister/brother" node.
* If you override onEnter, you shall call its parent's one, e.g., Node::onEnter().
* @lua NA
*/
virtual void onEnter() override;
/**
* Event callback that is invoked every time the Node leaves the 'stage'.
* If the Node leaves the 'stage' with a transition, this event is called when the transition finishes.
* During onExit you can't access a sibling node.
* If you override onExit, you shall call its parent's one, e.g., Node::onExit().
* @lua NA
*/
virtual void onExit() override;
};
#endif //MYGAME_POPUPLAYER_H
首先 PopupLayer继承自Layer类,你也可以继承自其他Layer类,如LayerColor,这样你可以获得不同的特性。这里仅仅定义了两个数据成员,一个std::string用于存储整个“窗口”的背景图文件名,一个EventListenerMouse指针存储鼠标监听器,稍后可以看到是如何使用它们的。最后,来看看添加了哪些成员方法。首先,我重写了基类的init()方法,如果你对cocos2dx不陌生,那么你应该知道在该方法中要做哪些事情。其次,我使用 CREATE_FUNC 宏来构建了一个默认的静态create()方法,这基本上也是cocos2dx的传统。为了进一步满足需求,我还提供了静态create()方法的一个重载,它将包含一个参数用于指定背景资源名。setBackgroundImage()方法可以用来设置和更改背景资源。okMenuItemCallback()和cancelMenuItemCallback()是“模态对话框”上两个按钮的回调方法。最后我还重写了基类的onEnter()和onExit()方法,这两个方法至关重要,稍后你将看到它们是如何相互配合完成整个功能的。
cocos2dx使用一个类对象前,总是先调用它的静态create()方法来创建该类的一个实例,所以我们先从它开始介绍。
PopupL