植物大战僵尸游戏开发教程专栏地址http://t.csdnimg.cn/m0EtD
对话框在游戏的交互中非常重要。在游戏中,对话框不仅可以提醒用户下达任务指令,而且还可以让用户进行操作,自定义游戏中的各种属性。对话框在游戏的交互中非常常见且大量使用。Cocos2d-x中并未实现对话框的功能。所以自定义实现一个对话框非常有必要。
代码文件位置
自定义对话框代码文件在Class\Based文件夹中,详细位置如下图所示。
Dialog.h
Dialog类继承Cocos2d-x中LayerColor类,LayerColor继承Layer,Layer在Cocos2d-x中表示一个层,Layer存在于场景中,一个场景可以包含多个层。LayerColor可以设置层的颜色。由于需要弹出一个对话框,所以背景需要变黑,所以Diaglog继承LayerColor。当弹出一个对话框时,背景就会变黑,让用户聚焦到此对话之中。详细的C++代码如下所示。
class Dialog :public LayerColor
{
public:/***创建触摸监听*/static EventListenerTouchOneByOne* createTouchtListener(Sprite* sprite);/***设置鼠标监听*/virtual void setMouseListener(EventListenerMouse* listener);protected:/***创建标签*/virtual Label* label(const std::string &name, const float& fontsize, Vec2 &vec2 = Vec2(0, 0), const float& space = 0, const Color3B& color = Color3B::GREEN, const float& scale = 1);/***创建按钮上的标签 */virtual void createLabel(Sprite* sprite, MenuItemImage* MenuItem, const std::string &name, Vec2 &vec2, float& fontsize, const float& space = 0, const Color3B& color = Color3B::GREEN);/***创建屏蔽层*/virtual void createShieldLayer(Node* node);/***删除层*/virtual void deleteDialog(){}/***设置鼠标监听是否可用*/virtual void setMouseListenerEnable(bool isEnable = true);CC_CONSTRUCTOR_ACCESS:Dialog();~Dialog();protected:Global* _global;EventListenerMouse* _mouseListener;private:Vec2 _phasePosition; /* 相差位置 */EventListenerTouchOneByOne* _shieldListener;
};
对话框函数可以移动,所以定义了触摸监听函数createTouchtListener()和setMouseListener()。对话框上需要有标签,所以定义了标签函数createLabel()。对话框上需要有各种按钮,所以定义了创建按钮的函数。当弹出对话框时,背景中的所有按钮及可点击的部分我们不希望可以再被点击,所以需要当弹出对话框时将背景触摸点击监听屏蔽,所以定义了屏蔽层函数createShieldLayer()。
Dialog.cpp
在源文件中实现了头文件中定义的函数。下面将对重要的函数进行介绍。
构造函数
构造函数对重要变量进行初始化。
Dialog::Dialog():_shieldListener(nullptr),_mouseListener(nullptr),_phasePosition(Vec2::ZERO),_global(Global::getInstance())
{
}
createTouchtListener()函数
函数有一个参数,传入一个Sprite(精灵),用于监听这个Sprite的触摸。创建完成后返回监听。
在函数中需要获取Sprite坐标以及触摸位置的坐标。计算这两个坐标之间的差值phasePosition,在触摸移动的过程中需要实时改变Sprite的位置,设置位置时需要减去phasePosition,这样才能平稳滑动Sprite,否则在首次接触Sprite的时候会导致Sprite瞬间移动到触摸位置。
EventListenerTouchOneByOne* Dialog::createTouchtListener(Sprite* sprite)
{/* 创建触摸监听 */static Vec2 phasePosition = Vec2(Vec2::ZERO);auto listener = EventListenerTouchOneByOne::create();listener->onTouchBegan = [&,sprite](Touch *t, Event *e) {if (sprite->getBoundingBox().containsPoint(t->getLocation())){phasePosition = t->getLocation() - sprite->getPosition();return true;}else return false;};listener->onTouchMoved = [=](Touch *t, Event *e) {sprite->setPosition(t->getLocation() - phasePosition);};Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, sprite);return listener;
}
createShieldLayer()函数
当弹出对话框时,背景中的所有按钮及可点击的部分我们不希望可以再被点击,所以需要当弹出对话框时将背景触摸点击监听屏蔽,所以定义了屏蔽层函数createShieldLayer()。
函数有一个参数Node,当将Node传入该函数,除该Node可以监听事件之外,场景中其他层的监听将会被屏蔽。
void Dialog::createShieldLayer(Node* node)
{// set shieldLayer_shieldListener = EventListenerTouchOneByOne::create();_shieldListener->onTouchBegan = [](Touch* touch, Event* event)-> bool { return true; };_shieldListener->setSwallowTouches(true);_eventDispatcher->addEventListenerWithSceneGraphPriority(_shieldListener, node);
}
label()函数
函数参数较多,参数表示的有文字本身、字体大小颜色、字间距、缩放比例、位置等。
Label* Dialog::label(const std::string &name, const float& fontsize, Vec2 &vec2, const float& space, const Color3B& color, const float& scale)
{auto label = Label::createWithTTF(name, GAME_FONT_NAME_1, fontsize);label->setScaleX(scale);label->setColor(color);label->setAdditionalKerning(space);//设置列间距label->enableShadow(Color4B(100, 20, 100, 255));//设置阴影label->setPosition(vec2);return label;
}
其他函数
void Dialog::setMouseListener(EventListenerMouse* listener)
{_mouseListener = listener;
}void Dialog::setMouseListenerEnable(bool isEnable)
{_mouseListener->setEnabled(isEnable);
}