Cocos2d-x中实现弹出对话框示例总结
来源:互联网 发布:java简历包装真实项目 编辑:程序博客网 时间:2024/05/29 04:06
在游戏中我们经常会看到弹出一个对话框让我们进行选择,今天我们就在cocos2dx中实现这个对话框。对话框说白了也是一个层,当我们点击某一个按钮的时候这个层被加进了当前的场景中,同时场景中的其他的层都是不可点击的,这个时候就涉及到触摸的优先级的一些问题,当然有些时候你也可以根据自己的需要让其他的层也可以点击,但是道理都是一样的,学会了这个其他的按照自己的要求去实现吧。下面我将弹出层单独分装成一个类,供我们调用。
/*对话框场景类的头文件*/
#ifndef _POP_SCENE_H_
#define _POP_SCENE_H_
#include "cocos2d.h"
using
namespace
cocos2d;
class
PopScene :
public
CCLayer
{
public
:
static
CCScene * scene();
bool
init();
CREATE_FUNC(PopScene);
private
:
//注册触摸事件,实现ccTouchBegan()方法
void
registerWithTouchDispatcher();
bool
ccTouchBegan(CCTouch * touch,CCEvent * pevent);
//在弹出的对话框上加俩个按钮,以下的函数是对应的按钮的处理事件
void
yesButton(CCObject * object);
void
noButton(CCObject * object);
//设置对话框的title
void
setTitle();
//设置对话框的文本内容
void
setContent();
//m_size代表的是对话框背景的大小
CCSize m_size;
//对话框的背景精灵
CCSprite * m_bgSprite;
};
#endif
/*对话框场景类的具体实现*/
#include "PopScene.h"
CCScene * PopScene::scene()
{
CCScene * scene = NULL;
do
{
scene = CCScene::create();
PopScene * layer = PopScene::create();
scene->addChild(layer);
}
while
(0);
return
scene;
}
bool
PopScene::init()
{
bool
bRet =
false
;
do
{
CC_BREAK_IF(!CCLayer::init());
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
//设置这个层的背景图片,并且设置其位置为整个屏幕的中点
CCSprite * background = CCSprite::create(
"background.png"
);
m_bgSprite = background;
background->setPosition(ccp(winSize.width/2,winSize.height/2));
this
->addChild(background);
//获得背景图片的大小
CCSize contentSize = background->getContentSize();
m_size = contentSize;
//添加俩个菜单在这个层中
CCMenuItemImage * item1 = CCMenuItemImage::create(
"btn-play-normal.png"
,
"btn-play-selected.png"
,
""
,
this
,menu_selector(PopScene::yesButton));
CCMenuItemImage * item2 = CCMenuItemImage::create(
"btn-highscores-normal.png"
,
"btn-highscores-selected.png"
,
""
,
this
,menu_selector(PopScene::noButton));
CCMenu * menu = CCMenu::create(item1,item2,NULL);
menu->alignItemsHorizontallyWithPadding(5);
menu->setPosition(ccp(contentSize.width/2,contentSize.height/3));
//kCCMenuHandlerPriority的值为-128,代表的是菜单按钮的触摸优先级
//设置menu优先级,这里设置为普通menu的二倍减一,原因看下边
menu->setTouchPriority(kCCMenuHandlerPriority*2-1);
background->addChild(menu);
//设置题目和文本内容
this
->setTitle();
this
->setContent();
this
->setTouchEnabled(
true
);
bRet =
true
;
}
while
(0);
return
bRet;
}
void
PopScene::registerWithTouchDispatcher()
{
//kCCMenuHandlerPriority=-128,将这个值设置为-128的二倍,可以比下边的层的优先级高
//而且ccTouchBegan的返回值为true,说明其他的层将接受不到这个触摸消息了,只有这个层上边的
//菜单的优先级比他还要打,所以它上边的菜单是可以接收到触摸消息的
CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(
this
,
kCCMenuHandlerPriority*2,
true
);
}
bool
PopScene::ccTouchBegan(CCTouch * touch,CCEvent * pevent)
{
return
true
;
}
//点击菜单按钮的时候调用的事件处理函数
void
PopScene::yesButton(CCObject * object)
{
this
->removeFromParentAndCleanup(
true
);
}
void
PopScene::noButton(CCObject * object)
{
this
->removeFromParentAndCleanup(
true
);
}
//设置这个层的题目
void
PopScene::setTitle()
{
//CCLabelTTF * title = CCLabelTTF::create("Tips","",24);
CCLabelBMFont * title = CCLabelBMFont::create(
"Tips"
,
"bitmapFontChinese.fnt"
);
title->setPosition(ccp(m_size.width/2,m_size.height-title->getContentSize().height/2));
m_bgSprite->addChild(title);
}
//设置层的内容
void
PopScene::setContent()
{
CCLabelTTF * content = CCLabelTTF::create(
"hello! everyone,welcome to www.jb51.net"
,
""
,24);
content->setPosition(ccp(m_size.width/2,m_size.height/2));
//设置ttf的文本域
content->setDimensions(CCSize(
this
->m_size.width-60,
this
->m_size.height-100));
//设置ttf的水平对齐方式
content->setHorizontalAlignment(kCCTextAlignmentLeft);
m_bgSprite->addChild(content);
}
//helloworld中按钮的回调函数
void
HelloWorld::menuCloseCallback(CCObject* pSender)
{
PopScene* popLayer = PopScene::create();
this
->addChild(popLayer);
}
上文来自:http://www.jb51.net/article/55074.htm
在游戏中,我们常常需要实现弹出一个模态对话框,比如说游戏暂停,退出提示对话框等
对话框特点如下:
1.可定制的,比如说背景图,标题,文本,按钮等,根据需要添加和设置
2.需要屏蔽对话框下层的触摸
3.为了友好的效果显示,把不可触摸的部分变为灰色
先来看一张效果图:
为了完成这样一个效果,思路如下:
1.设计一个弹出对话框的类PopupLayer,继承于LayerColor,这样子我们就可以设置背景版透明,看起来好像把对话框下层的变灰暗了
1.
setColor(ccc3(
0
,
0
,
0
));
2.
setOpacity(
128
);
2.添加触摸事件,屏蔽下层触摸,也就是在Layer中设置不向下传递
1.
//add layer touch event
2.
auto listener = EventListenerTouchOneByOne::create();
3.
listener->setSwallowTouches(
true
);
//不向下传递触摸
4.
listener->onTouchBegan = CC_CALLBACK_2(PopupLayer::onTouchBegan,
this
);
5.
listener->onTouchMoved = CC_CALLBACK_2(PopupLayer::onTouchMoved,
this
);
6.
listener->onTouchEnded = CC_CALLBACK_2(PopupLayer::onTouchEnded,
this
);
7.
auto dispatcher = Director::getInstance()->getEventDispatcher();
8.
dispatcher->addEventListenerWithSceneGraphPriority(listener,
this
);
3.PopupLayer类 实现 可定制对话框标题,按钮,文本,背景图片等
1.
//标题
2.
void
setTitle(
const
char
* title,
int
fontsize =
20
);
3.
//文本
4.
void
setContentText(
const
char
* text,
int
fontsize =
20
,
int
padding =
50
,
int
paddintTop =
100
);
5.
//设置button回调事件
6.
void
setCallbackFunc(Ref* target, SEL_CallFuncN callfun);
7.
//添加button
8.
bool addButton(
const
char
* normalImage,
const
char
* selectedImage,
const
char
* title,
int
tag =
0
);
4.按钮回调函数实现也比较简单,首先设置外部的回调对象和回调函数
1.
Ref* m_callbackListener;
//回调对象
2.
SEL_CallFuncN m_callback;
//回调函数
3.
4.
//设置按钮的回调函数
5.
void
PopupLayer::setCallbackFunc(Ref* target, SEL_CallFuncN callfun){
6.
m_callbackListener = target;
7.
m_callback = callfun;
8.
}
然后在PopupLayer类中比如说我们添加一个菜单按钮
1.
// 创建图片菜单按钮
2.
auto item = MenuItemImage::create(
3.
normalImage,
4.
selectedImage,
5.
CC_CALLBACK_1(PopupLayer::buttonCallBack,
this
));
6.
item->setTag(tag);
设置button回调函数,然后由这个回调函数去调用外部的button监听函数,然后关闭对话框
1.
//button回调函数
2.
void
PopupLayer::buttonCallBack(Ref* pSender){
3.
Node* node = dynamic_cast<Node*>(pSender);
4.
CCLog(
"【====PopupLayer::buttonCallBack====】touch tag: %d"
, node->getTag());
5.
if
(m_callback && m_callbackListener){
6.
(m_callbackListener->*m_callback)(node);
7.
}
8.
this
->removeFromParent();}
5.然后用法也比较简单,如果需要对话框内容显示中文,可以参考:cocos2d-x 3.0 使用Sax解析xml文档(解决中文显示问题)这篇文章
1.
//弹出对话框
2.
pl = PopupLayer::create(
"BackGround.png"
,Size(
400
,
350
));
3.
pl->setTitle(
"title"
);
4.
pl->setContentText(
"Are you sure exit?"
,
20
,
60
,
250
);
5.
pl->setCallbackFunc(
this
, callfuncN_selector(WelcomeScene::popButtonCallback));
//设置按钮回调
6.
pl->addButton(
"pop_button.png"
,
"pop_button.png"
,
"yes"
,
0
);
7.
pl->addButton(
"pop_button.png"
,
"pop_button.png"
,
"no"
,
1
);
8.
this
->addChild(pl);
外部回调函数实现,根据tag判断点了什么按钮
1.
void
WelcomeScene::popButtonCallback(Node *pNode){
2.
CCLog(
"【=====WelcomeScene::popButtonCallback======】button call back. tag: %d"
, pNode->getTag());
3.
//exit
4.
if
(pNode->getTag() ==
0
){
5.
Director::getInstance()->end();
6.
}
7.
}
恩,思路大概这样子,完整的对话框类如下,亲们可以复制直接使用
01.
#pragma once
02.
03.
#include
"cocos2d.h"
04.
#include
"cocos-ext.h"
05.
06.
using namespace cocos2d;
07.
using namespace cocos2d::extension;
08.
09.
class
PopupLayer :
public
LayerColor{
10.
public
:
11.
PopupLayer();
12.
~PopupLayer();
13.
14.
virtual bool init();
15.
CREATE_FUNC(PopupLayer);
16.
static
PopupLayer* create(
const
char
* backgroundImage,Size dialogSize);
17.
18.
//touch事件监听 屏蔽向下触摸
19.
bool onTouchBegan(Touch *touch, Event *event);
20.
void
onTouchMoved(Touch *touch, Event *event);
21.
void
onTouchEnded(Touch* touch, Event* event);
22.
23.
//标题
24.
void
setTitle(
const
char
* title,
int
fontsize =
20
);
25.
//文本
26.
void
setContentText(
const
char
* text,
int
fontsize =
20
,
int
padding =
50
,
int
paddintTop =
100
);
27.
//设置button回调事件
28.
void
setCallbackFunc(Ref* target, SEL_CallFuncN callfun);
29.
//添加button
30.
bool addButton(
const
char
* normalImage,
const
char
* selectedImage,
const
char
* title,
int
tag =
0
);
31.
32.
virtual
void
onEnter();
33.
virtual
void
onExit();
34.
35.
void
backgroundFinish();
36.
37.
private
:
38.
39.
void
buttonCallBack(Ref* pSender);
40.
41.
// 文字内容两边的空白区
42.
int
m_contentPadding;
43.
int
m_contentPaddingTop;
44.
45.
Size m_dialogContentSize;
46.
47.
Ref* m_callbackListener;
48.
SEL_CallFuncN m_callback;
49.
50.
//set and get
51.
CC_SYNTHESIZE_RETAIN(Menu*, m__pMenu, MenuButton);
52.
CC_SYNTHESIZE_RETAIN(Sprite*, m__sfBackGround, SpriteBackGround);
53.
CC_SYNTHESIZE_RETAIN(Scale9Sprite*, m__s9BackGround, Sprite9BackGround);
54.
CC_SYNTHESIZE_RETAIN(LabelTTF*, m__ltTitle, LabelTitle);
55.
CC_SYNTHESIZE_RETAIN(LabelTTF*, m__ltContentText, LabelContentText);
56.
};
cpp文件实现如下:
001.
#include
"PopupLayer.h"
002.
003.
PopupLayer::PopupLayer():
004.
m__pMenu(NULL)
005.
, m_contentPadding(
0
)
006.
, m_contentPaddingTop(
0
)
007.
, m_callbackListener(NULL)
008.
, m_callback(NULL)
009.
, m__sfBackGround(NULL)
010.
, m__s9BackGround(NULL)
011.
, m__ltContentText(NULL)
012.
, m__ltTitle(NULL)
013.
{
014.
015.
}
016.
017.
PopupLayer::~PopupLayer(){
018.
CC_SAFE_RELEASE(m__pMenu);
019.
CC_SAFE_RELEASE(m__sfBackGround);
020.
CC_SAFE_RELEASE(m__ltContentText);
021.
CC_SAFE_RELEASE(m__ltTitle);
022.
CC_SAFE_RELEASE(m__s9BackGround);
023.
}
024.
025.
bool PopupLayer::init(){
026.
if
(!LayerColor::init()){
027.
return
false
;
028.
}
029.
// 初始化需要的 Menu
030.
Menu* menu = Menu::create();
031.
menu->setPosition(CCPointZero);
032.
setMenuButton(menu);
033.
034.
//add layer touch event
035.
auto listener = EventListenerTouchOneByOne::create();
036.
listener->setSwallowTouches(
true
);
037.
listener->onTouchBegan = CC_CALLBACK_2(PopupLayer::onTouchBegan,
this
);
038.
listener->onTouchMoved = CC_CALLBACK_2(PopupLayer::onTouchMoved,
this
);
039.
listener->onTouchEnded = CC_CALLBACK_2(PopupLayer::onTouchEnded,
this
);
040.
auto dispatcher = Director::getInstance()->getEventDispatcher();
041.
dispatcher->addEventListenerWithSceneGraphPriority(listener,
this
);
042.
043.
setColor(ccc3(
0
,
0
,
0
));
044.
setOpacity(
128
);
045.
046.
return
true
;
047.
}
048.
049.
bool PopupLayer::onTouchBegan(Touch *touch, Event *event){
050.
return
true
;
051.
}
052.
053.
void
PopupLayer::onTouchMoved(Touch *touch, Event *event){
054.
055.
}
056.
057.
void
PopupLayer::onTouchEnded(Touch* touch, Event* event){
058.
059.
}
060.
061.
PopupLayer* PopupLayer::create(
const
char
* backgroundImage, Size dialogSize){
062.
063.
PopupLayer* layer = PopupLayer::create();
064.
065.
// layer->setSpriteBackGround(Sprite::create(backgroundImage));
066.
layer->setSprite9BackGround(Scale9Sprite::create(backgroundImage));
067.
068.
layer->m_dialogContentSize = dialogSize;
069.
070.
return
layer;
071.
}
072.
073.
void
PopupLayer::setTitle(
const
char
* title,
int
fontsize
/* = 20 */
){
074.
LabelTTF* label = LabelTTF::create(title,
""
,fontsize);
075.
setLabelTitle(label);
076.
}
077.
078.
void
PopupLayer::setContentText(
const
char
*text,
int
fontsize,
int
padding,
int
paddingTop){
079.
LabelTTF* ltf = LabelTTF::create(text,
""
, fontsize);
080.
setLabelContentText(ltf);
081.
m_contentPadding = padding;
082.
m_contentPaddingTop = paddingTop;
083.
}
084.
085.
void
PopupLayer::setCallbackFunc(Ref* target, SEL_CallFuncN callfun){
086.
m_callbackListener = target;
087.
m_callback = callfun;
088.
}
089.
090.
bool PopupLayer::addButton(
const
char
* normalImage,
const
char
* selectedImage,
const
char
* title,
int
tag
/* = 0 */
){
091.
092.
auto size = Director::getInstance()->getWinSize();
093.
auto center = Point(size.width /
2
, size.height /
2
);
094.
095.
// 创建图片菜单按钮
096.
auto item = MenuItemImage::create(
097.
normalImage,
098.
selectedImage,
099.
CC_CALLBACK_1(PopupLayer::buttonCallBack,
this
));
100.
item->setTag(tag);
101.
item->setPosition(center);
102.
103.
// 添加文字说明并设置位置
104.
Size itemSize = item->getContentSize();
105.
LabelTTF* ttf = LabelTTF::create(title,
""
,
20
);
106.
ttf->setColor(Color3B(
0
,
0
,
0
));
107.
ttf->setPosition(Point(itemSize.width /
2
, itemSize.height /
2
));
108.
item->addChild(ttf);
109.
110.
getMenuButton()->addChild(item);
111.
112.
return
true
;
113.
}
114.
115.
void
PopupLayer::buttonCallBack(Ref* pSender){
116.
Node* node = dynamic_cast<Node*>(pSender);
117.
CCLog(
"【====PopupLayer::buttonCallBack====】touch tag: %d"
, node->getTag());
118.
if
(m_callback && m_callbackListener){
119.
(m_callbackListener->*m_callback)(node);
120.
}
121.
this
->removeFromParent();
122.
}
123.
124.
void
PopupLayer::onEnter(){
125.
LayerColor::onEnter();
126.
127.
Size winSize = CCDirector::getInstance()->getWinSize();
128.
Point pCenter = Point(winSize.width /
2
, winSize.height /
2
);
129.
130.
// Size contentSize ;
131.
// 设定好参数,在运行时加载
132.
//如果没有设置 ContentSize ,那么采取的方案是,窗口大小与传入图片一样大
133.
// if (getContentSize().equals(this->getParent()->getContentSize())) {
134.
// getSpriteBackGround()->setPosition(ccp(winSize.width / 2, winSize.height / 2));
135.
// this->addChild(getSpriteBackGround(), 0, 0);
136.
// contentSize = getSpriteBackGround()->getTexture()->getContentSize();
137.
// } else {
138.
// Scale9Sprite *background = getSprite9BackGround();
139.
// background->setContentSize(getContentSize());
140.
// background->setPosition(ccp(winSize.width / 2, winSize.height / 2));
141.
// this->addChild(background, 0, 0);
142.
// contentSize = getContentSize();
143.
// }
144.
//添加背景图片
145.
Scale9Sprite *background = getSprite9BackGround();
146.
background->setContentSize(m_dialogContentSize);
147.
background->setPosition(Point(winSize.width /
2
, winSize.height /
2
));
148.
this
->addChild(background,
0
,
0
);
149.
150.
// 弹出效果
151.
Action* popupLayer = Sequence::create(
152.
ScaleTo::create(
0.0
,
0.0
),
153.
ScaleTo::create(
0.2
,
1.05
),
154.
ScaleTo::create(
0.2
,
0.95
),
155.
ScaleTo::create(
0.1
,
1.0
),
156.
CallFunc::create(CC_CALLBACK_0(PopupLayer::backgroundFinish,
this
)),
157.
NULL
158.
);
159.
background->runAction(popupLayer);
160.
161.
162.
163.
}
164.
165.
void
PopupLayer::backgroundFinish(){
166.
167.
Size winSize = CCDirector::getInstance()->getWinSize();
168.
Point pCenter = Point(winSize.width /
2
, winSize.height /
2
);
169.
170.
// 添加按钮,并设置其位置
171.
this
->addChild(getMenuButton());
172.
float
btnWidth = m_dialogContentSize.width / (getMenuButton()->getChildrenCount() +
1
);
173.
174.
Vector<Node*> vector = getMenuButton()->getChildren();
175.
Ref* pObj = NULL;
176.
int
i =
0
;
177.
for
(Node* pObj : vector){
178.
Node* node = dynamic_cast<Node*>(pObj);
179.
node->setPosition(Point( winSize.width /
2
- m_dialogContentSize.width /
2
+ btnWidth * (i +
1
), winSize.height /
2
- m_dialogContentSize.height /
3
));
180.
i++;
181.
}
182.
183.
// 显示对话框标题
184.
if
(getLabelTitle()){
185.
getLabelTitle()->setPosition(ccpAdd(pCenter, ccp(
0
, m_dialogContentSize.height /
2
-
35
.0f)));
186.
this
->addChild(getLabelTitle());
187.
}
188.
189.
// 显示文本内容
190.
if
(getLabelContentText()){
191.
CCLabelTTF* ltf = getLabelContentText();
192.
ltf->setPosition(ccp(winSize.width /
2
, winSize.height /
2
));
193.
ltf->setDimensions(CCSizeMake(m_dialogContentSize.width - m_contentPadding *
2
, m_dialogContentSize.height - m_contentPaddingTop));
194.
ltf->setHorizontalAlignment(kCCTextAlignmentLeft);
195.
this
->addChild(ltf);
196.
}
197.
}
198.
199.
200.
201.
void
PopupLayer::onExit(){
202.
203.
CCLog(
"popup on exit."
);
204.
CCLayerColor::onExit();
205.
}
1、弹出层的触摸优先级,操作与显示相一致
2、定制按钮个数
3、窗口的大小可变
- 如果没有设置 ContentSize ,那么采取的方案是,窗口大小与传入图片一样大。
- 如果设置了ContentSize,则将窗口设定为指定大小。这时候需要将背景图片进行缩放,如何缩放? 【答案】是利用9宫格图CCScale9Sprite缩放图片,缩放带圆角的图片。原理如下:
4、回调函数的实现方案
5、onEnter动态创建弹出层
- 其一,实时设置,实时刷新。比如在 static PopupLayer* create(const char* gackgroundImage) 的实现里面,创建一个精灵,并设置好图片,添加到当前层,如果调用了 setContentSize 我们再在此方法获取精灵后去修改这个精灵的大小
- 其二,保留属性,动态组建。也就是说前面一些封装的函数比如setTitle()、setContentText(),addButton()、setCallbackFunc()只用于设置属性参数(即给变量赋值)。参数设置好以后,在一个适当的执行时期,根据以上参数,动态创建符合需求的精灵/层,而这个操作在 onEnter 里尤为合适。
封装
//PopupLayer.h
#include "cocos2d.h"
#include "cocos-ext.h"
USING_NS_CC;
USING_NS_CC_EXT;
class PopupLayer : public CCLayer{
public:
PopupLayer();
~PopupLayer();
virtual bool init();
//需要重写触摸注册函数,重新给定触摸级别
virtual void registerWithTouchDispatc
//重写触摸函数,返回true,屏蔽其它层,达到“模态”效果
bool ccTouchBegan(CCTouch *pTouch, 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 paddingTop=100);
//设置上层对象和上层回调函数,用于回调时传递CCNode参数
void setCallBackFunc(CCObject* target, SEL_CallFuncN callfun);
//添加menuItem按钮,封装了一个函数,传入些必要的参数
bool addButton(const char* normalImage, const char* selectedImage, const char* title, int tag=0);
//为了在显示层时的属性生效,选择在onEnter里动态生成
virtual void onEnter();
virtual void onExit();
CREATE_FUNC(PopupLayer);
private:
void buttonCallBack(CCObject* pSender);
//文字内容两边的空白区域
int m_contentPadding;
int m_contentPaddingTop;
CCObject* m_callbackListener;
SEL_CallFuncN m_callback;
//定义了CCMenu*类型变量m_pMenu, 并且直接定义默认的set/get方法
CC_SYNTHESIZE_RETAIN(CCMenu*, m_pMenu, MenuButton);
CC_SYNTHESIZE_RETAIN(CCSprite*, m_sfBackGround, SpriteBackGround);
CC_SYNTHESIZE_RETAIN(CCScale9Sprite*, m_s9BackGround, Sprite9BackGround);
CC_SYNTHESIZE_RETAIN(CCLabelTTF*, m_ltTitle, LabelTitle);
CC_SYNTHESIZE_RETAIN(CCLabelTTF*, m_ltContentText, LabelContentText);
};
//PopupLayer.cpp
#include "PopupLayer.h"
USING_NS_CC;
// 构造函数中变量设初值
PopupLayer::PopupLayer()
{
m_contentPadding = 0;
m_contentPaddingTop = 0;
m_pMenu = NULL;
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_s9BackGround);
CC_SAFE_RELEASE(m_ltContentText);
CC_SAFE_RELEASE(m_ltTitle);
}
//初始化
bool PopupLayer::init()
{
if ( !CCLayer::init() ){
return false;
}
this->setContentSize(CCSizeZero);
//初始化需要的Menu
CCMenu* menu = CCMenu::create();
menu->setPosition(CCPointZero);
setMenuButton(menu);
//set()方法
setTouchEnabled(true);
//开启触摸响应 return true;
}
//重写触摸注册函数,重新给定触摸级别
void PopupLayer::registerWithTouchDispatc
// 这里的触摸优先级设置为-128,与CCMenu同级,保证了屏蔽下方的触摸
CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, -128, true);
}
//触摸函数ccTouchBegan,返回true
bool PopupLayer::ccTouchBegan( CCTouch *pTouch, CCEvent *pEvent ){
return true;
}
//创建一个弹出层,给背景精灵变量赋值
PopupLayer* PopupLayer::create( const char* backgroundImage ){
PopupLayer* popup = PopupLayer::create();
popup->setSpriteBackGround(CCSprite::create(backgroundImage));
popup->setSprite9BackGround(CCScale9Sprite::create(backgroundImage));
return popup;
}
//给标题变量赋值
void PopupLayer::setTitle( const char* title, int fontsize ){
CCLabelTTF* ltfTitle = CCLabelTTF::create(title, "Arial", fontsize);
ltfTitle->setColor(ccc3(0, 0, 0));
setLabelTitle(ltfTitle);
}
//给文本变量赋值
void PopupLayer::setContentText( const char* text, int fontsize, int padding, int paddingTop ){
CCLabelTTF* content = CCLabelTTF::create(text, "Arial", fontsize);
content->setColor(ccc3(0, 0, 0));
setLabelContentText(content);
m_contentPadding = padding;
m_contentPaddingTop = paddingTop;
}
//给下层层变量和回调函数变量赋值
void PopupLayer::setCallBackFunc( CCObject* target, SEL_CallFuncN callfun ){
m_callbackListener = target;
m_callback = callfun;
}
//给menu菜单变量添加Item
bool PopupLayer::addButton( const char* normalImage, const char* selectedImage, const char* title, int tag ){
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
CCPoint center = ccp(winSize.width/2, winSize.height/2);
// 创建图片菜单按钮
CCMenuItemImage* menuImage = CCMenuItemImage::create(
normalImage, selectedImage, this, menu_selector(PopupLayer::buttonCallBack));
menuImage->setTag(tag);
menuImage->setPosition(center);
// 添加文字说明并设置位置
CCSize menuSize = menuImage->getContentSize();
CCLabelTTF* ttf = CCLabelTTF::create(title, "Arial", 15);
ttf->setColor(ccc3(0, 0, 0));
ttf->setPosition(ccp(menuSize.width/2, menuSize.height/2));
menuImage->addChild(ttf);
getMenuButton()->addChild(menuImage);
return true;
}
//销毁弹出框,传递参数node给下层
void PopupLayer::buttonCallBack( CCObject* pSender ){
CCNode* node = dynamic_cast(pSender);
CCLog("touch tag: %d", node->getTag());
if (m_callback && m_callbackListener)
{
//执行HelloWorld层的回调函数,传递node参数
(m_callbackListener->*m_callback)(node);
}
this->removeFromParentAndClean
up(true);
}
//全部参数都设定好后,在运行时动态加载
void PopupLayer::onEnter(){
CCLayer::onEnter();
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
CCPoint center = ccp(winSize.width/2, winSize.height/2);
CCSize contentSize;
// 设定好参数,在运行时加载
if (getContentSize().equals(CCSizeZero)){
getSpriteBackGround()->setPosition(center);
this->addChild(getSpriteBackGround(),0,0);
contentSize = getSpriteBackGround()->getTexture()->getContentSize();
}
else{
CCScale9Sprite* background = getSprite9BackGround();
background->setContentSize(getContentSize());
background->setPosition(center);
this->addChild(background, 0);
contentSize = getContentSize();
}
//添加按钮,并根据Item的个数设置其位置
this->addChild(getMenuButton());
float btnWidth = contentSize.width / (getMenuButton()->getChildrenCount()+1);
CCArray* array = getMenuButton()->getChildren();
CCObject* pObj = NULL;
int i = 0;
CCARRAY_FOREACH(array, pObj){
CCNode* node = dynamic_cast(pObj);
node->setPosition(ccp(winSize.width/2 - contentSize.width/2 + btnWidth*(i+1),
winSize.height/2 - contentSize.height/3)); i++;
}
// 显示对话框标题
if (getLabelTitle()){
getLabelTitle()->setPosition(ccpAdd(center, ccp(0, contentSize.height/2 - 25.0f)));
this->addChild(getLabelTitle());
}
//显示文本内容
if (getLabelContentText()){
CCLabelTTF* ltf = getLabelContentText();
ltf->setPosition(center);
ltf->setDimensions(CCSizeMake(contentSize.width - m_contentPadding*2, contentSize.height - m_contentPaddingTop));
ltf->setHorizontalAlignment(kCCTextAlignmentLeft);
this->addChild(ltf);
}
//弹出效果
CCSequence *popupActions = 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(popupActions);
}
//退出
void PopupLayer::onExit(){
CCLayer::onExit();
}
弹出层调用:
// 定义一个弹出层,传入一张背景图片
PopupLayer* popup = PopupLayer::create("popupBackGround.png");
// ContentSize是可选的设置,可以不设置,如果设置则把它当做9图缩放
//popup->setContentSize(CCSizeMake(400, 360));
popup->setTitle("Message");
popup->setContentText("Most people... blunder round this city.", 20, 50, 150);
// 设置回调函数,回调传回一个CCNode以获取tag判断点击的按钮
// 这只是作为一种封装实现,如果使用delegate那就能够更灵活的控制参数了
popup->setCallBackFunc(this, callfuncN_selector(HelloWorld::buttonCallBack));
//添加按钮,设置图片、文字,tag信息
popup->addButton("button.png", "button.png", "Ok", 0);
popup->addButton("button.png", "button.png", "Cancel", 1);
this->addChild(popup);
测试截图:
这样,对话框的基本模型就完成了,它实现了以下功能:
- 一个可以弹出的对话框实现
- 模态窗口的实现(需要逻辑的控制)
- 多按钮的支持,位置自适应,提供回调函数
- 提供标题和内容设置
- 支持 九图,控制适应弹出框大小
- Cocos2d-x中实现弹出对话框示例总结
- cocos2d-x中实现对话框
- cocos2d-x 弹出对话框的设计与实现
- Cocos2d-x 弹出对话框的设计与实现
- Cocos2d-x 弹出对话框的设计与实现
- Cocos2d-x 弹出对话框的设计与实现
- Cocos2D-X弹出对话框的实现与封装
- Cocos2D-X弹出对话框的实现与封装
- Cocos2D-X弹出对话框的实现与封装
- cocos2d-x3.x 弹出对话框的设计与实现
- cocos2d-x 弹出对话框播放视频
- cocos2d-x 中layer如何实现模态对话框
- Quick-Cocos2d-x-3.2中示例Coinfilp总结(二)
- Quick-Cocos2d-x-3.2中示例Coinfilp总结(一)
- cocos2d-x学习日志(12) --弹出对话框的设计与实现
- Cocos2d-x添加一个按钮弹出一个android对话框
- cocos2d-x 模态对话框的实现
- Cocos2d-x 实现模态对话框
- 面试要这样“厚脸皮”才能成功!
- vsftpd配置文件详解
- eclipse中tomcat端口占用情况
- 配置spring-mvc + simple-spring-memcached
- linux shell 字符串操作(长度,查找,替换)详解
- Cocos2d-x中实现弹出对话框示例总结
- 修改UISearBar的背景颜色
- springMVC中微信公众平台开发
- ajax 原生请求数据
- [算法]计算算式
- 使用Simple-Spring-Memcached注解做缓存操作
- Intent的显式隐式调
- 火车进站问题,堆栈的使用
- 关键字static和this