咱們時常須要這麼些功能,彈出一個層,給與用戶一些提示,這也是一種模態窗口,在沒有對當前對話框進行確認的時候,不能繼續往下操做。node
咱們設計一個對話框,對話框上有幾個按鈕(個數可定製),固然有個標題,會讓別人一眼看出它之功用,裏面能夠有些詳細的提示文字,須要是模態窗口,並且窗口的大小可變,這樣可以更好的適應不一樣的屏幕的大小。固然還有一個重要的功能,彈出效果 ~ 雖然從技術角度來講,實現起來並不難,或者說很是簡單,但這會以一個很好的用戶體驗展現給用戶。iphone
1.彈出框類函數
PopupLayer.h測試
1 //
2 // PopupLayer.h 3 // PopupDemo 4 //
5 // Created by IDEA-MAC03 on 13-10-10. 6 //
7 // 8
9 #ifndef __PopupDemo__PopupLayer__ 10 #define __PopupDemo__PopupLayer__
11
12 #include "cocos2d.h"
13 #include "cocos-ext.h"
14 using namespace cocos2d; 15 using namespace cocos2d::extension; 16 using namespace std; 17
18
19
20 class PopupLayer:public CCLayer 21 { 22
23 public: 24 PopupLayer(); 25 ~PopupLayer(); 26
27 virtual bool init(); 28 CREATE_FUNC(PopupLayer); 29
30 // 須要重寫觸摸註冊函數,從新給定觸摸級別
31 virtual void registerWithTouchDispatcher(void); 32 // 重寫觸摸函數,永遠返回 true ,屏蔽其它層,達到 「模態」 效果
33 bool ccTouchBegan(cocos2d::CCTouch *pTouch,cocos2d::CCEvent *pEvent); 34 // 構架,並設置對話框背景圖片
35 static PopupLayer* create(const char* backgroundImage); 36
37 // 它能夠顯示標題,而且設定顯示文字大小
38 void setTitle(const char*title,int fontsize = 20); 39 // 文本內容,padding 爲文字到對話框兩邊預留的距離,這是可控的,距上方的距離亦是如此
40 void setContentText(const char *text, int fontsize = 20, int padding = 50, int paddintTop = 100); 41 // 回調函數,當點擊按鈕後,咱們關閉彈出層的同事,須要一個回調函數,以通知咱們點擊了哪一個按鈕(若是有多個)
42 void setCallbackFunc(CCObject* target, SEL_CallFuncN callfun); 43 // 爲了添加按鈕方面,封裝了一個函數,傳入些必要的參數
44 bool addButton(const char* normalImage, const char* selectedImage, const char* title, int tag = 0); 45
46 // 爲了在顯示層時以前的屬性生效,選擇在 onEnter 裏動態展現
47 virtual void onEnter(); 48 virtual void onExit(); 49
50 private: 51
52 void buttonCallback(CCObject* pSender); 53
54 // 文字內容兩邊的空白區
55 int m_contentPadding; 56 int m_contentPaddingTop; 57
58 CCObject* m_callbackListener; 59 SEL_CallFuncN m_callback; 60
61 CC_SYNTHESIZE_RETAIN(CCMenu*, m__pMenu, MenuButton); 62 CC_SYNTHESIZE_RETAIN(CCSprite*, m__sfBackGround, SpriteBackGround); 63 CC_SYNTHESIZE_RETAIN(CCScale9Sprite*, m__s9BackGround, Sprite9BackGround); 64 CC_SYNTHESIZE_RETAIN(CCLabelTTF*, m__ltTitle, LabelTitle); 65 CC_SYNTHESIZE_RETAIN(CCLabelTTF*, m__ltContentText, LabelContentText); 66
67 }; 68
69
70
71
72 #endif /* defined(__PopupDemo__PopupLayer__) */
PopupLayer.cppthis
1 //
2 // PopupLayer.cpp 3 // PopupDemo 4 //
5 // Created by IDEA-MAC03 on 13-10-10. 6 //
7 // 8
9 #include "PopupLayer.h"
10
11
12
13 PopupLayer::PopupLayer(): 14 m__pMenu(NULL) 15 ,m_contentPadding(0) 16 ,m_contentPaddingTop(0) 17 ,m_callbackListener(NULL) 18 ,m_callback(NULL) 19 ,m__sfBackGround(NULL) 20 ,m__s9BackGround(NULL) 21 ,m__ltContentText(NULL) 22 ,m__ltTitle(NULL) 23 { 24
25 } 26
27 PopupLayer::~PopupLayer() 28 { 29 CC_SAFE_RELEASE(m__pMenu); 30 CC_SAFE_RELEASE(m__sfBackGround); 31 CC_SAFE_RELEASE(m__ltContentText); 32 CC_SAFE_RELEASE(m__ltTitle); 33 CC_SAFE_RELEASE(m__s9BackGround); 34 } 35
36 bool PopupLayer::init() 37 { 38 bool bRef = false; 39 do
40 { 41 CC_BREAK_IF(!CCLayer::init()); 42 this->setContentSize(CCSizeZero); 43 // 初始化須要的 Menu
44 CCMenu* menu = CCMenu::create(); 45 menu->setPosition(CCPointZero); 46 setMenuButton(menu); 47 setTouchEnabled(true); 48 bRef = true; 49 } while (0); 50 return bRef; 51 } 52
53
54 void PopupLayer::registerWithTouchDispatcher() 55 { 56 // 這裏的觸摸優先級設置爲 -128 這保證了,屏蔽下方的觸摸
57 CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, -128, true); 58 } 59
60 bool PopupLayer::ccTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent) 61 { 62 CCLog("PopupLayer touch"); 63 return true; 64 } 65
66
67 PopupLayer* PopupLayer::create(const char *backgroundImage) 68 { 69 PopupLayer* ml = PopupLayer::create(); 70 ml->setSpriteBackGround(CCSprite::create(backgroundImage)); 71 ml->setSprite9BackGround(CCScale9Sprite::create(backgroundImage)); 72 return ml; 73 } 74
75
76 void PopupLayer::setTitle(const char*title,int fontsize) 77 { 78 CCLabelTTF* ltfTitle = CCLabelTTF::create(title, "", fontsize); 79 setLabelTitle(ltfTitle); 80 } 81
82 void PopupLayer::setContentText(const char *text, int fontsize, int padding, int paddingTop){ 83 CCLabelTTF* ltf = CCLabelTTF::create(text, "", fontsize); 84 setLabelContentText(ltf); 85 m_contentPadding = padding; 86 m_contentPaddingTop = paddingTop; 87 } 88
89 void PopupLayer::setCallbackFunc(cocos2d::CCObject *target, SEL_CallFuncN callfun) 90 { 91 m_callbackListener = target; 92 m_callback = callfun; 93 } 94
95
96 bool PopupLayer::addButton(const char *normalImage, const char *selectedImage, const char *title, int tag){ 97 CCSize winSize = CCDirector::sharedDirector()->getWinSize(); 98 CCPoint pCenter = ccp(winSize.width / 2, winSize.height / 2); 99
100 // 建立圖片菜單按鈕
101 CCMenuItemImage* menuImage = CCMenuItemImage::create(normalImage, selectedImage, this, menu_selector(PopupLayer::buttonCallback)); 102 menuImage->setTag(tag); 103 menuImage->setPosition(pCenter); 104
105 // 添加文字說明並設置位置
106 CCSize imenu = menuImage->getContentSize(); 107 CCLabelTTF* ttf = CCLabelTTF::create(title, "", 20); 108 ttf->setColor(ccc3(0, 0, 0)); 109 ttf->setPosition(ccp(imenu.width / 2, imenu.height / 2)); 110 menuImage->addChild(ttf); 111
112 getMenuButton()->addChild(menuImage); 113 return true; 114 } 115
116
117 void PopupLayer::buttonCallback(cocos2d::CCObject *pSender){ 118 CCNode* node = dynamic_cast<CCNode*>(pSender); 119 CCLog("touch tag: %d", node->getTag()); 120 if (m_callback && m_callbackListener){ 121 (m_callbackListener->*m_callback)(node); 122 } 123 this->removeFromParentAndCleanup(true); 124 } 125
126
127
128 void PopupLayer::onEnter() 129 { 130 CCLayer::onEnter(); 131
132 CCSize winSize = CCDirector::sharedDirector()->getWinSize(); 133 CCPoint pCenter = ccp(winSize.width / 2, winSize.height / 2); 134
135 CCSize contentSize; 136 // 設定好參數,在運行時加載
137 if (getContentSize().equals(CCSizeZero)) 138 { 139 getSpriteBackGround()->setPosition(ccp(winSize.width / 2, winSize.height / 2)); 140 this->addChild(getSpriteBackGround(),0,0); 141 contentSize = getSpriteBackGround()->getTexture()->getContentSize(); 142 }else
143 { 144 CCScale9Sprite *background = getSprite9BackGround(); 145 background->setContentSize(getContentSize()); 146 background->setPosition(ccp(winSize.width / 2, winSize.height / 2)); 147 this->addChild(background,0); 148 contentSize = getContentSize(); 149 } 150
151
152 // 添加按鈕,並設置其位置
153 this->addChild(getMenuButton()); 154 float btnWidth = contentSize.width/(getMenuButton()->getChildrenCount()+1); 155
156 CCArray* array = getMenuButton()->getChildren(); 157 CCObject* pObj = NULL; 158 int i = 0; 159 CCARRAY_FOREACH(array, pObj) 160 { 161 CCNode* node = dynamic_cast<CCNode*>(pObj); 162 node->setPosition(ccp(winSize.width / 2 - contentSize.width / 2 + btnWidth * (i + 1), winSize.height / 2 - contentSize.height / 3)); 163 i++; 164 } 165
166 // 顯示對話框標題
167 if (getLabelTitle()) 168 { 169 getLabelTitle()->setPosition(ccpAdd(pCenter, ccp(0, contentSize.height / 2 - 35.0f))); 170 this->addChild(getLabelTitle()); 171 } 172
173 // 顯示文本內容
174 if (getLabelContentText()) 175 { 176 CCLabelTTF* ltf = getLabelContentText(); 177 ltf->setPosition(ccp(winSize.width / 2, winSize.height / 2)); 178 ltf->setDimensions(CCSizeMake(contentSize.width - m_contentPadding * 2, contentSize.height - m_contentPaddingTop)); 179 ltf->setHorizontalAlignment(kCCTextAlignmentLeft); 180 this->addChild(ltf); 181 } 182
183 CCAction* popupLayer = CCSequence::create(CCScaleTo::create(0.0, 0.0), 184 CCScaleTo::create(0.06, 1.05), 185 CCScaleTo::create(0.08, 0.95), 186 CCScaleTo::create(0.08, 1.0), NULL); 187 this->runAction(popupLayer); 188
189 } 190
191
192 void PopupLayer::onExit() 193 { 194 CCLog("popup on exit."); 195 CCLayer::onExit(); 196 }
2.測試代碼spa
HelloWorldScene.h.net
1 #ifndef __HELLOWORLD_SCENE_H__ 2 #define __HELLOWORLD_SCENE_H__
3
4 #include "cocos2d.h"
5
6 class HelloWorld : public cocos2d::CCLayer 7 { 8 public: 9 // Method 'init' in cocos2d-x returns bool, instead of 'id' in cocos2d-iphone (an object pointer)
10 virtual bool init(); 11
12 // there's no 'id' in cpp, so we recommend to return the class instance pointer
13 static cocos2d::CCScene* scene(); 14
15 // a selector callback
16 void menuCloseCallback(CCObject* pSender); 17
18 // preprocessor macro for "static create()" constructor ( node() deprecated )
19 CREATE_FUNC(HelloWorld); 20
21 void menuCallback(cocos2d::CCObject *pSender); 22 void popupLayer(); 23 void buttonCallback(cocos2d::CCNode *pNode); 24 }; 25
26 #endif // __HELLOWORLD_SCENE_H__
HelloWorldScene.cpp設計
1 #include "HelloWorldScene.h"
2 #include "SimpleAudioEngine.h"
3 #include "PopupLayer.h"
4
5 using namespace cocos2d; 6 using namespace CocosDenshion; 7
8 CCScene* HelloWorld::scene() 9 { 10 // 'scene' is an autorelease object
11 CCScene *scene = CCScene::create(); 12
13 // 'layer' is an autorelease object
14 HelloWorld *layer = HelloWorld::create(); 15
16 // add layer as a child to scene
17 scene->addChild(layer); 18
19 // return the scene
20 return scene; 21 } 22
23 // on "init" you need to initialize your instance
24 bool HelloWorld::init() 25 { 26 ////////////////////////////// 27 // 1. super init first
28 if ( !CCLayer::init() ) 29 { 30 return false; 31 } 32
33 CCSize winSize = CCDirector::sharedDirector()->getWinSize(); 34 CCPoint pointCenter = ccp(winSize.width / 2, winSize.height / 2); 35
36 // 添加背景圖片
37 CCSprite* background = CCSprite::create("HelloWorld.png"); 38 background->setPosition(pointCenter); 39 background->setScale(1.5f); 40 this->addChild(background); 41
42 // 添加菜單
43 CCMenu* menu = CCMenu::create(); 44
45 CCMenuItemFont* menuItem = CCMenuItemFont::create("popup", this, menu_selector(HelloWorld::menuCallback)); 46 menuItem->setPosition(ccp(winSize.width / 2, winSize.height / 2)); 47 menuItem->setColor(ccc3(0, 0, 0)); 48 menu->addChild(menuItem); 49
50
51 menu->setPosition(CCPointZero); 52 this->addChild(menu); 53
54
55
56 return true; 57 } 58
59
60 void HelloWorld::menuCallback(cocos2d::CCObject *pSender){ 61 popupLayer(); 62 } 63
64 void HelloWorld::popupLayer() 65 { 66 // 定義一個彈出層,傳入一張背景圖
67 PopupLayer* pl = PopupLayer::create("useDialogBox0u00001.png"); 68 // ContentSize 是可選的設置,能夠不設置,若是設置把它看成 9 圖縮放
69 pl->setContentSize(CCSizeMake(400, 360)); 70 pl->setTitle("吾名一葉"); 71 pl->setContentText("嬌蘭傲梅世人賞,卻少幽芬暗裏藏。不看百花共爭豔,獨愛疏櫻一枝香。", 20, 50, 150); 72 // 設置回調函數,回調傳回一個 CCNode 以獲取 tag 判斷點擊的按鈕 73 // 這只是做爲一種封裝實現,若是使用 delegate 那就可以更靈活的控制參數了
74 pl->setCallbackFunc(this, callfuncN_selector(HelloWorld::buttonCallback)); 75 // 添加按鈕,設置圖片,文字,tag 信息
76 pl->addButton("shopBtn0s01.png", "shopBtn0s02.png", "肯定", 0); 77 pl->addButton("bagButton0b1.png", "bagButton0b2.png", "取消", 1); 78 // 添加到當前層
79 this->addChild(pl); 80 } 81
82
83
84 void HelloWorld::buttonCallback(cocos2d::CCNode *pNode){ 85 CCLog("button call back. tag: %d", pNode->getTag()); 86 } 87
88 void HelloWorld::menuCloseCallback(CCObject* pSender) 89 { 90 CCDirector::sharedDirector()->end(); 91
92 #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
93 exit(0); 94 #endif
95 }
如上,完成了對話框的基本模型,它實現瞭如下功能:code
固然還有許多其它並無照顧到的功能,或者不完善的地方,這就須要用戶本身擴展,定製了,如,這樣一個層,至少應該是單例的,任什麼時候候只應該存在一個,能夠用單例模式實現,對於彈出層的內容方面,這裏只有標題和內容,而且標題位置固定,按鈕的位置還能夠更靈活的設置等。orm
注:
在設置按鈕位置的時候有可能出現按鈕位置不對,特調整以下:
1 CCMenuItemImage* itemImage = dynamic_case<CCMenuItemImage*>(array->objectAtIndex(0)); 2 int count = getMenuButton()->getChildrenCount(); 3 int btnWidth = itemImage->getContentSize().width; 4 int padingWidth = (contentSize.width - btnWidth * count) / (count + 1); 5 CCARRAY_FOREACH(array, obj) 6 { 7 CCNode* node = dynamic_cast<CCNode*>(obj); 8 node->setAnchorPoint(ccp(0, 0.5f)); 9 node->setPosition(ccp(visibSize.width * 0.5f - contentSize.width * 0.5f + padingWidth * (i + 1) + btnWidth * i, visibSize.height * 0.5f - contentSize.height / 3)); 10 i++
11 }
原文連接:http://blog.csdn.net/rexuefengye/article/details/12610909