在游戏开发中,为了获得更好的交互效果,经常使用对话框,cocos实现对话框也比较容易,说到底对话框也是一个Layer。我们在添加Layer之前首先对对话框进行一定的设置,之后在Layer的OnEnter方法中对界面进行一个动态的加载,另外我们需要重写OnTouchBegin方法,以屏蔽其他的触摸事件。下面是我实现的一个简单对话框
创建C++类DialogLayer实现对话框界面,头文件如下
#ifndef _DialogLayer_ #define _DialogLayer_ #include "cocos2d.h" USING_NS_CC; class DialogLayer :public Layer { public: DialogLayer(); ~DialogLayer(); virtual bool init(); CREATE_FUNC(DialogLayer); //virtual void registerWithTouchDispatcher(void); bool onTouchBegan(Touch *touch,Event *unused_event); static DialogLayer * create(const char* backgroundImage); void setTitle(const char* title,int fontsize=20); void setContentText(const char* text,int fontsize=20,int padding=50,int paddintTop=100); void setCallbackFunc(CCObject* target,SEL_CallFuncN callfun); bool addButton(const char* normalImage,const char* selectedImage,const char* title,int tag=0); virtual void onEnter(); private: void buttonCallback(CCObject* pSender); // 文字内容两边的空白区 int m_contentPadding; int m_contentPaddingTop; CCObject* m_callbackListener; SEL_CallFuncN m_callback; //利用cocos中的宏来添加get与set方法,最后的参数表示方法名中get与set之后相接的部分 CC_SYNTHESIZE_RETAIN(Menu*,m_pMenu,MenuButton); CC_SYNTHESIZE_RETAIN(Sprite*,m_sfBackGround,SpriteBackGround); CC_SYNTHESIZE_RETAIN(LabelTTF*,m_ltTitle,LabelTitle); CC_SYNTHESIZE_RETAIN(LabelTTF*,m_ltContentText,LabelContentText); }; #endifC++实现部分:
#include "DialogLayer.h" USING_NS_CC; DialogLayer::DialogLayer(): m_pMenu(NULL),m_contentPadding(0),m_contentPaddingTop(0),m_callbackListener(NULL),m_callback(NULL),m_sfBackGround(NULL),m_ltContentText(NULL),m_ltTitle(NULL) { } DialogLayer::~DialogLayer(){ CC_SAFE_RELEASE(m_pMenu); CC_SAFE_RELEASE(m_sfBackGround); CC_SAFE_RELEASE(m_ltContentText); CC_SAFE_RELEASE(m_ltTitle); } bool DialogLayer::init(){ if(!Layer::init()){ return false; } this->setContentSize(Size::ZERO); // 初始化需要的 Menu Menu* menu = Menu::create(); menu->setPosition(0,0); setMenuButton(menu); setTouchEnabled(true); return true; } //屏蔽向下的监听事件 bool DialogLayer::onTouchBegan(Touch *pTouch,Event *pEvent){ return true; } DialogLayer* DialogLayer::create(const char *backgroundImage){ DialogLayer* ml = DialogLayer::create(); ml->setSpriteBackGround(Sprite::create(backgroundImage)); return ml; } //设置标题 void DialogLayer::setTitle(const char *title,int fontsize){ LabelTTF* ltfTitle = LabelTTF::create(title,"",fontsize); setLabelTitle(ltfTitle); } //设置对话框要显示的内容 void DialogLayer::setContentText(const char *text,int fontsize,int padding,int paddingTop){ LabelTTF* ltf = LabelTTF::create(text,fontsize); setLabelContentText(ltf); m_contentPadding = padding; m_contentPaddingTop = paddingTop; } //设置回调接口 void DialogLayer::setCallbackFunc(cocos2d::CCObject *target,SEL_CallFuncN callfun){ m_callbackListener = target; m_callback = callfun; } bool DialogLayer::addButton(const char *normalImage,const char *selectedImage,const char *title,int tag){ Size winSize = Director::getInstance()->getVisibleSize(); Point pCenter(winSize.width / 2,winSize.height / 2); // 创建图片菜单按钮 MenuItemImage* menuImage = MenuItemImage::create(normalImage,selectedImage,this,menu_selector(DialogLayer::buttonCallback)); menuImage->setTag(tag); menuImage->setPosition(pCenter); // 添加文字说明并设置位置 Size imenu = menuImage->getContentSize(); LabelTTF* ttf = LabelTTF::create(title,20); ttf->setColor(Color3B::BLACK); ttf->setPosition(imenu.width / 2,imenu.height / 2); menuImage->addChild(ttf,1); getMenuButton()->addChild(menuImage,1); return true; } void DialogLayer::buttonCallback(cocos2d::CCObject *pSender){ Node* node = dynamic_cast<Node*>(pSender); //当回调接口不为空时,执行回调接口 if (m_callback && m_callbackListener){ (m_callbackListener->*m_callback)(node); } this->removeFromParent(); } void DialogLayer::onEnter(){ Layer::onEnter(); Size winSize = Director::getInstance()->getVisibleSize(); Size contentSize; // 设定好参数,在运行时加载 getSpriteBackGround()->setPosition(winSize.width / 2,winSize.height / 2); this->addChild(getSpriteBackGround(),0); contentSize = getSpriteBackGround()->getTexture()->getContentSize(); // 添加按钮,并设置其位置 this->addChild(getMenuButton()); float btnWidth = contentSize.width / (getMenuButton()->getChildrenCount() + 1); Vector<Node*> vecArray = getMenuButton()->getChildren(); CCObject* pObj = NULL; int i = 0; for(auto& e : vecArray){ Node* node = dynamic_cast<Node*>(e); node->setPosition(Point(winSize.width/2 - contentSize.width/2+btnWidth*(i+1),winSize.height - contentSize.height-20)); i++; } // 显示对话框标题 if (getLabelTitle()){ getLabelTitle()->setPosition(winSize.width/2,winSize.height/2 + (contentSize.height / 2 - 35.0f)); this->addChild(getLabelTitle()); } // 显示文本内容 if (getLabelContentText()){ LabelTTF* ltf = getLabelContentText(); ltf->setPosition(winSize.width / 2,winSize.height / 2); ltf->setDimensions(CCSizeMake(contentSize.width - m_contentPadding * 2,contentSize.height - m_contentPaddingTop)); ltf->setHorizontalAlignment(TextHAlignment::LEFT);//设置对齐方式 this->addChild(ltf); } // 弹出效果,我们可以实现自己的动画效果 Action* popupLayer = Sequence::create(ScaleTo::create(0.0,0.0),ScaleTo::create(0.06,1.05),ScaleTo::create(0.08,0.95),1.0),NULL); this->runAction(popupLayer); }接下来在HelloWorld层中加入该对话框,我们在回调接口中保存了一个Tag,可以根据这个Tag来判断点击的是哪一个按钮
void HelloWorld::menuCloseCallback(Ref* pSender) { showDialog(); } void HelloWorld::showDialog(){ // 定义一个弹出层,传入一张背景图 DialogLayer* pl = DialogLayer::create("BackGround.png"); pl->setTitle("MyDialog_Title"); pl->setContentText("This is my dialog_contenttext with a pop",20,60,250); // 设置回调函数,回调传回一个 CCNode 以获取 tag 判断点击的按钮 // 这只是作为一种封装实现,如果使用 delegate 那就能够更灵活的控制参数了 pl->setCallbackFunc(this,callfuncN_selector(HelloWorld::buttonCallback)); // 添加按钮,设置图片,文字,tag 信息 pl->addButton("btn_n.png","btn_p.png","Yes",0); pl->addButton("btn_n.png","No",1); // 添加到当前层 this->addChild(pl,1); } void HelloWorld::buttonCallback(cocos2d::Node *pNode){ //根据tag来判断点击的时哪个按钮 log("button call back. tag: %d",pNode->getTag()); }原文链接:https://www.f2er.com/cocos2dx/345249.html