cocos2d基础学习--自定义对话框实现

前端之家收集整理的这篇文章主要介绍了cocos2d基础学习--自定义对话框实现前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

在游戏开发中,为了获得更好的交互效果,经常使用对话框,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);

};


#endif
C++实现部分:
#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

猜你在找的Cocos2d-x相关文章