Search…

Kỹ Thuật Popup với Cocos2d-x 3.x.x

29/09/20204 min read
Hướng dẫn xây dựng 1 Menu Game - Popup Component.

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.

Menu game Sins

Đặ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
Menu game Sins.

Ý 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ỗi Popup

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;
        }
});
Popup trong game Sins.

Download code

IO Stream

IO Stream Co., Ltd

30 Trinh Dinh Thao, Hoa Thanh ward, Tan Phu district, Ho Chi Minh city, Vietnam
+84 28 22 00 11 12
developer@iostream.co

383/1 Quang Trung, ward 10, Go Vap district, Ho Chi Minh city
Business license number: 0311563559 issued by the Department of Planning and Investment of Ho Chi Minh City on February 23, 2012

©IO Stream, 2013 - 2024