Giới thiệu
Với 1 menu có đầy đủ thông tin, sự tương tác của người chơi với game, nội dung, ... và cách thiết kế vô cùng đặc sắc sẽ là yếu tố tăng trải nghiệm của người chơi, trong bài viết này hướng dẫn tạo 1 menu như vậy - Popup Component.
Đặt vấn đề
Trong Menu Game trên gồm 1 số các thành phần (Component) như sau:
- Cài đặt (Setting):
PopupSetting
- Thông tin (About):
PopupAbout
- Bộ sưu tập (Remuneration):
PopupRemuneration
Ý tưởng
Khi người chơi chọn 1 trong các Button Options (ở phía dưới góc trái) thì xuất hiện các Popup tương ứng với chức năng của mỗi Button đi từ ngoài phía bên phải vào. Khi người chơi muốn thoát khỏi Popup hiện tại sẽ có 1 Button Back và rồi các Popup tương ứng sẽ đi vào trong (từ trái sang phải).
Hiện thực
Tất cả các thành phần (Components) ở trên đều có chung 1 số thành phần như là Background, Title, và các hiệu ứng xuất hiện (Appear), biến mất (Disappear).
Popup class
Header
///@ Popup.h #ifndef __SINS_POPUP_H__ #define __SINS_POPUP_H__ #include "string" #include "cocos2d.h" #include "ui/CocosGUI.h" #include "Config.h" #include "Resources.h" using namespace cocos2d::ui; USING_NS_CC; class Popup : public Node { public: CREATE_FUNC(Popup); virtual bool init(); virtual void onExit(); virtual void disappear(); virtual void appear(); virtual void setTitlePopup(std::string _titlePopup); protected: Layer *m_popupLayer; Size backgroundContentSize; Size visibleSize; Point origin; ActionInterval *m_appearAction; ActionInterval *m_disappearAction; private: }; #endif /* defined (__SINS_POPUP_H__) */
Phân tích
Trong class này, bạn cần quan tâm tới những điều sau:
appear()
: phương thức được gọi tới khi 1 Popup cần xuất hiện.disappear()
: phương thức được gọi tới khi 1 Popup cần biến mất.m_popupLayer
: chứa các thành phần riêng biệt của mỗiPopup
.
Source
///@ Popup.cpp #include "Popup.h" bool Popup::init() { if (!Node::init()) return false; m_visibleSize = Director::getInstance()->getVisibleSize(); m_origin = Director::getInstance()->getVisibleOrigin(); m_popupLayer = Layer::create(); m_popupLayer->setAnchorPoint(Vec2::ZERO); m_popupLayer->setPosition(Vec2(m_visibleSize.width + m_origin.x, m_origin.y)); addChild(m_popupLayer); auto _background = Sprite::create(SPR_RES_PATH[SPR_BACKGROUND_POPUP]); _background->setAnchorPoint(Vec2::ZERO); _background->setPosition(Point::ZERO); m_popupLayer->addChild(_background); backgroundContentSize = _background->getContentSize() m_appearAction = TargetedAction::create(m_popupLayer, MoveTo::create(POPUP_FADING_TIME, Vec2(m_visibleSize.width - backgroundContentSize.width + m_origin.x, m_origin.y))); m_disappearAction = TargetedAction::create(m_popupLayer, MoveTo::create(POPUP_FADING_TIME, Vec2(m_visibleSize.width + m_origin.x, m_origin.y))); m_appearAction->retain(); m_disappearAction->retain(); return true; } void Popup::disappear() { this->runAction(m_disappearAction->clone()); } void Popup::appear() { this->runAction(m_appearAction->clone()); } void Popup::setTitlePopup(std::string _titlePopup) { auto _title = Label::createWithBMFont( FNT_RES_PATH[FNT_EN_COMMON], Singleton<LanguageManager>::getInstance()->getStringForKey(_titlePopup).c_str()); _title->setAdditionalKerning(7.0f); _title->setPosition(Point(backgroundContentSize.width / 2 + m_origin.x, backgroundContentSize.height * 8 / 10 + m_origin.y)); _title->setColor(COLOR_TEXT_YELOW); _title->setScale(1.5f); m_popupLayer->addChild(_title); } void Popup::onExit() { m_appearAction->release(); m_disappearAction->release(); Node::onExit(); }
PopupSetting
Header
///@ PopupSetting.h #ifndef __POPUP_SETTING_H__ #define __POPUP_SETTING_H__ #include "Popup.h" enum { eSldMusic = 0, eSldSound }; class PopupSetting : public Popup { public: CREATE_FUNC(PopupSetting); bool init(); virtual void onExit(); void sliderEvent(Ref *pSender, Slider::EventType type); void checkBoxSelectedEvent(Ref* pSender, CheckBox::EventType type); void changeVolumeOfAudio(int _typeAudio, float _valueVolume); protected: private: CheckBox *m_checkboxMuteAllSound; Slider *m_sliderOptionMusics[2]; }; #endif /* defined (__POPUP_SETTING_H__) */
Source
///@ PopupSetting.cpp #include "PopupSetting.h" bool PopupSetting::init() { if (!Popup::init()) return false; setTitlePopup("STR_SETTING_TITLE"); for (int index = 0; index < 2; index++) { // label auto _label = Label::createWithBMFont(FNT_RES_PATH[FNT_EN_COMMON], Singleton<LanguageManager>::getInstance()->getStringForKey(SRT_SETTING[index]).c_str()); _label->setAdditionalKerning(7.0f); _label->setPosition(Vec2(backgroundContentSize.width / 2 + m_origin.x, backgroundContentSize.height * (7 - index*2) / 10 + m_origin.y)); _label->setColor(COLOR_TEXT_YELOW); m_popupLayer->addChild(_label, Z_POPUP); // slider bar m_sliderOptionMusic[index] = Slider::create(); m_sliderOptionMusic[index]->setTag(index); m_sliderOptionMusic[index]->loadBarTexture(SPR_RES_PATH[SPR_SLIDEBAR_OFF]); m_sliderOptionMusic[index]->loadSlidBallTextures(SPR_RES_PATH[SPR_SLIDER_NODE_PRESS], SPR_RES_PATH[SPR_SLIDER_NODE_NORMAL], SPR_RES_PATH[SPR_SLIDER_NODE_DISABLE]); m_sliderOptionMusic[index]->loadProgressBarTexture(SPR_RES_PATH[SPR_SLIDEBAR_ON]); m_sliderOptionMusic[index]->setPosition(Vec2(backgroundContentSize.width / 2 + m_origin.x, backgroundContentSize.height * (6 - index * 2) / 10 + m_origin.y)); m_sliderOptionMusic[index]->addEventListener(CC_CALLBACK_2(PopupSetting::sliderEvent, this)); m_popupLayer->addChild(m_sliderOptionMusic[index], Z_POPUP); } /// init checkbox // label auto _labelMuteAllSound = Label::createWithBMFont(FNT_RES_PATH[FNT_EN_COMMON], Singleton<LanguageManager>::getInstance()->getStringForKey("STR_SETTING_MUTEALLSOUND").c_str()); _labelMuteAllSound->setAdditionalKerning(7.0f); _labelMuteAllSound->setPosition(Vec2(backgroundContentSize.width * 2 / 3 + m_origin.x, backgroundContentSize.height * 1 / 4 + m_origin.y)); _labelMuteAllSound->setColor(COLOR_TEXT_YELOW); m_popupLayer->addChild(_labelMuteAllSound, Z_POPUP); // checkbox m_checkboxMuteAllSound = CheckBox::create(SPR_RES_PATH[SPR_CHECKBOX_NORMAL], SPR_RES_PATH[SPR_CHECKBOX_NORMAL_PRESS], SPR_RES_PATH[SPR_CHECKBOX_ACTIVE], SPR_RES_PATH[SPR_CHECKBOX_NORMAL_DISABLE], SPR_RES_PATH[SPR_CHECKBOX_ACTIVE_DISABLE]); m_checkboxMuteAllSound->setPosition(Vec2(backgroundContentSize.width * 1 / 3 + m_origin.x, backgroundContentSize.height * 1 / 4 + m_origin.y)); m_checkboxMuteAllSound->addEventListener(CC_CALLBACK_2(PopupSetting::checkBoxSelectedEvent, this)); m_popupLayer->addChild(m_checkboxMuteAllSound, Z_POPUP); return true; } void PopupSetting::sliderEvent(Ref *pSender, Slider::EventType type) { switch (type) { case Slider::EventType::ON_PERCENTAGE_CHANGED: { Slider* _slider = dynamic_cast<Slider*>(pSender); float _valueVolume = float(_slider->getPercent()) / 100; changeVolumeOfAudio(_slider->getTag(), _valueVolume); break; } default: break; } } void PopupSetting::checkBoxSelectedEvent(Ref* pSender, CheckBox::EventType type) { switch (type) { case CheckBox::EventType::SELECTED: { m_sliderOptionMusic[eSldMusic]->setPercent(0); m_sliderOptionMusic[eSldSound]->setPercent(0); // m_audio->setEffectsVolume(0.0f); // m_audio->setBackgroundMusicVolume(0.0f); break; } case CheckBox::EventType::UNSELECTED: { m_sliderOptionMusic[eSldSound]->setPercent(50); m_sliderOptionMusic[eSldMusic]->setPercent(50); //m_audio->setEffectsVolume(0.5f); //m_audio->setBackgroundMusicVolume(0.5f); break; } default: break; } } void PopupSetting::changeVolumeOfAudio(int _typeAudio, float _valueVolume) { /* if (_typeAudio == eSldSound) m_audio->setEffectsVolume(_valueVolume); else m_audio->setBackgroundMusicVolume(_valueVolume); */ } void PopupSetting::onExit() { Popup::onExit(); }
Sử dụng Popup trong Scene
Khởi tạo
#include "PopupSetting.h" ... PopupSetting *m_popupSetting = PopupSetting::create(); m_popupSetting->retain(); addChild(m_popupSetting);
Khi click vào Button Setting trong Menu Game sẽ xuất hiện Popup Setting.
m_btnSetting = Button::create(SPR_BUTTON_SHORT[SPR_BUTTON_NORMAL_SHORT], SPR_BUTTON_SHORT[SPR_BUTTON_SELECT_SHORT], SPR_BUTTON_SHORT[SPR_BUTTON_DISABLE_SHORT]); m_btnSetting->setAnchorPoint(Vec2::ZERO); m_btnSetting->setPosition(Vec2::ZERO); m_btnSetting->addTouchEventListener([&](Ref* sender, Widget::TouchEventType type) { switch (type) { case ui::Widget::TouchEventType::BEGAN: break; case ui::Widget::TouchEventType::ENDED: m_popupSetting->appear(); break; default: break; } }); addChild(m_btnSetting , Z_POPUP_BACKGROUND);
Khi cick vào Button Back trong Menu Game thì Popup Setting sẽ mất đi.
m_btnBack ->addTouchEventListener([&](Ref* sender, Widget::TouchEventType type) { switch (type) { case ui::Widget::TouchEventType::BEGAN: break; case ui::Widget::TouchEventType::ENDED: m_popupSetting->disappear(); break; default: break; } });