cocos2dx 弹出框 网上有好多实现 但是都不是想要的
此弹出框功能:自定义添加按钮 title 内容 模态实现
直接上代码:
头文件:
#ifndef _POP_LAYER_H_
#define _POP_LAYER_H_
#include "cocos2d.h"
#include "extensions/cocos-ext.h"
USING_NS_CC;
using namespace cocos2d::extension;
class PopupLayer: public CCLayer{
public:
PopupLayer();
~PopupLayer();
virtual bool init();
CREATE_FUNC(PopupLayer);
//void registerWithTouchDispatcher(void);
//bool onTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent);
static PopupLayer* 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(Ref* target, SEL_CallFuncN callfun);
bool addButton(const char* normalImage, const char* selectedImage, const char* title, int tag = 0);
virtual void onEnter();
virtual void onExit();
void buttonCallback(Ref* pSender);
bool onTouchBegan(Touch* touch, Event* event);
void onTouchMoved(Touch* touch, Event* event);
void onTouchEnded(Touch* touch, Event* event);
private:
// 文字内容两边的空白区
int m_contentPadding;
int m_contentPaddingTop;
CCObject* m_callbackListener;
SEL_CallFuncN m_callback;
CC_SYNTHESIZE_RETAIN(Menu*, m__pMenu, MenuButton);
CC_SYNTHESIZE_RETAIN(Sprite*, m__sfBackGround, SpriteBackGround);
CC_SYNTHESIZE_RETAIN(Scale9Sprite*, m__s9BackGround, Sprite9BackGround);
CC_SYNTHESIZE_RETAIN(CCLabelTTF*, m__ltTitle, LabelTitle);
CC_SYNTHESIZE_RETAIN(CCLabelTTF*, m__ltContentText, LabelContentText);
};
#endif;
类名字 随便起的 大家就不要吐槽了………………
cpp文件:
#include "Poplayer.h"
PopupLayer::PopupLayer():
m__pMenu(NULL)
, m_contentPadding(0)
, m_contentPaddingTop(0)
, m_callbackListener(NULL)
, m_callback(NULL)
, m__sfBackGround(NULL)
, m__s9BackGround(NULL)
, m__ltContentText(NULL)
, m__ltTitle(NULL)
{
}
PopupLayer::~PopupLayer(){
CC_SAFE_RELEASE(m__pMenu);
CC_SAFE_RELEASE(m__sfBackGround);
CC_SAFE_RELEASE(m__ltContentText);
CC_SAFE_RELEASE(m__ltTitle);
CC_SAFE_RELEASE(m__s9BackGround);
}
bool PopupLayer::init(){
bool bRef = false;
do{
CC_BREAK_IF(!CCLayer::init());
this->setContentSize(CCSizeZero);
// 初始化需要的 Menu
CCMenu* menu = CCMenu::create();
menu->setPosition(CCPointZero);
setMenuButton(menu);
setTouchEnabled(true);
auto listener = EventListenerTouchOneByOne::create();
listener->setSwallowTouches(true);
listener->onTouchBegan = CC_CALLBACK_2(PopupLayer::onTouchBegan, this);
listener->onTouchMoved = CC_CALLBACK_2(PopupLayer::onTouchMoved, this);
listener->onTouchEnded = CC_CALLBACK_2(PopupLayer::onTouchEnded, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
bRef = true;
}while(0);
return bRef;
}
bool PopupLayer::onTouchBegan(Touch* pTouch, Event* event)
{
CCLog("PopupLayer touch");
return true;
}
void PopupLayer::onTouchMoved(Touch* touch, Event* event)
{
log("move");
}
void PopupLayer::onTouchEnded(Touch* touch, Event* event)
{
log("ended");
}
PopupLayer* PopupLayer::create(const char *backgroundImage){
PopupLayer* ml = PopupLayer::create();
ml->setSpriteBackGround(Sprite::create(backgroundImage));
ml->setSprite9BackGround(Scale9Sprite::create(backgroundImage));
return ml;
}
void PopupLayer::setTitle(const char *title, int fontsize){
CCLabelTTF* ltfTitle = LabelTTF::create(title, "Arial", fontsize);
setLabelTitle(ltfTitle);
}
void PopupLayer::setContentText(const char *text, int fontsize, int padding, int paddingTop){
CCLabelTTF* ltf = CCLabelTTF::create(text, "Arial", fontsize);
setLabelContentText(ltf);
m_contentPadding = padding;
m_contentPaddingTop = paddingTop;
}
void PopupLayer::setCallbackFunc(Ref* target, SEL_CallFuncN callfun){
m_callbackListener = target;
m_callback = callfun;
}
bool PopupLayer::addButton(const char *normalImage, const char *selectedImage, const char *title, int tag){
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
CCPoint pCenter = ccp(winSize.width / 2, winSize.height / 2);
// 创建图片菜单按钮
CCMenuItemImage* menuImage = CCMenuItemImage::create(normalImage, selectedImage, this, menu_selector(PopupLayer::buttonCallback));
menuImage->setTag(tag);
menuImage->setPosition(pCenter);
// 添加文字说明并设置位置
CCSize imenu = menuImage->getContentSize();
CCLabelTTF* ttf = CCLabelTTF::create(title, "Arial", 20);
ttf->setColor(ccc3(0, 0, 0));
ttf->setPosition(ccp(imenu.width / 2, imenu.height / 2));
menuImage->addChild(ttf);
getMenuButton()->addChild(menuImage);
return true;
}
void PopupLayer::buttonCallback(Ref* pSender){
Node* node = (Node*)pSender;
CCLog("touch tag: %d", node->getTag());
if (m_callback && m_callbackListener){
(m_callbackListener->*m_callback)(node);
}
int tag = node->getTag();
switch(tag)
{
case 0:
{
}
case 1:
{
}
default:
break;
}
this->removeFromParent();
}
void PopupLayer::onEnter(){
CCLayer::onEnter();
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
CCPoint pCenter = ccp(winSize.width / 2, winSize.height / 2);
CCSize contentSize;
// 设定好参数,在运行时加载
if (getContentSize().equals(CCSizeZero)) {
getSpriteBackGround()->setPosition(ccp(winSize.width / 2, winSize.height / 2));
this->addChild(getSpriteBackGround(), 0, 0);
contentSize = getSpriteBackGround()->getTexture()->getContentSize();
} else {
Scale9Sprite *background = getSprite9BackGround();
background->setContentSize(getContentSize());
background->setPosition(ccp(winSize.width / 2, winSize.height / 2));
this->addChild(background, 0, 0);
contentSize = getContentSize();
}
// 添加按钮,并设置其位置
this->addChild(getMenuButton());
float btnWidth = contentSize.width / (getMenuButton()->getChildrenCount() + 1);
auto array = getMenuButton()->getChildren();
Ref* pObj = NULL;
for(int i = 0;i< array.capacity();i++)
{
Node* node = array.at(i);
node->setPosition(ccp( winSize.width / 2 - contentSize.width / 2 + btnWidth * (i + 1), winSize.height / 2 - contentSize.height / 3));
}
// 显示对话框标题
if (getLabelTitle()){
getLabelTitle()->setPosition(ccpAdd(pCenter, ccp(0, contentSize.height / 2 - 35.0f)));
this->addChild(getLabelTitle());
}
// 显示文本内容
if (getLabelContentText()){
CCLabelTTF* ltf = getLabelContentText();
ltf->setPosition(ccp(winSize.width / 2, winSize.height / 2));
ltf->setDimensions(CCSizeMake(contentSize.width - m_contentPadding * 2, contentSize.height - m_contentPaddingTop));
ltf->setHorizontalAlignment(kCCTextAlignmentLeft);
this->addChild(ltf);
}
// 弹出效果
CCAction* popupLayer = CCSequence::create(CCScaleTo::create(0.0, 0.0),
CCScaleTo::create(0.06, 1.05),
CCScaleTo::create(0.08, 0.95),
CCScaleTo::create(0.08, 1.0), NULL);
this->runAction(popupLayer);
}
void PopupLayer::onExit(){
CCLog("popup on exit.");
CCLayer::onExit();
}
使用方法:
PopupLayer* pl = PopupLayer::create("popuplayer/BackGround.png");
// ContentSize 是可选的设置,可以不设置,如果设置把它当作 9 图缩放
pl->setContentSize(CCSizeMake(400, 350));
pl->setTitle("test");
pl->setContentText(G2U("你好,弹出框"),20, 60, 250);
// 设置回调函数,回调传回一个 CCNode 以获取 tag 判断点击的按钮
// 这只是作为一种封装实现,如果使用 delegate 那就能够更灵活的控制参数了
pl->setCallbackFunc(this,callfuncN_selector(LoginScene::buttonCallback));
// 添加按钮,设置图片,文字,tag 信息
pl->addButton("popuplayer/pop_button.png", "popuplayer/pop_button.png", G2U("确定"), 0);
pl->addButton("popuplayer/pop_button.png", "popuplayer/pop_button.png", G2U("取消"), 1);
// 添加到当前层
this->addChild(pl);
G2U是 gbk转UTF_8 要不然的话 中文会乱码
函数如下:
char* G2U(const char* gb2312)
{
int len = MultiByteToWideChar(CP_ACP, 0, gb2312, -1, NULL, 0);
wchar_t* wstr = new wchar_t[len+1];
memset(wstr, 0, len+1);
MultiByteToWideChar(CP_ACP, 0, gb2312, -1, wstr, len);
len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
char* str = new char[len+1];
memset(str, 0, len+1);
WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, NULL, NULL);
if(wstr) delete[] wstr;
return str;
}
希望大家喜欢