遊戲開發cocos2d-x實戰(5) -- UI系統

Cocos2d-x提供了GUI元素,繪製豐富多彩的界面,其中包括:Label、Menu、MenuItems、Buttons和ScrollView、Slider、LoadBar、RadioButton、CheckBox、Layout、定時器等。

1、Label

Label支持四種方式的標籤創建。並新增了陰影Shadow、輪廓Outline、發光Glow效果的支持。還支持文字內容的行間距、文字間距、自動換行的設置。

(1)createWithSystemFont
Label::createWithSystemFont(
const std::string& text,//字符串內容
const std::string& font, //字體(字體名稱、或字體文件)
float fontSize,//字號
const Size& dimensions , //尺寸大小,默認不設置尺寸
TextHAlignment hAlignment, //水平對齊方式,默認左對齊:EFT
TextVAlignment vAlignment //垂直對齊方式,默認頂部 ::TOP
);
(2) createWithTTF
Label::createWithTTF(
const std::string& text,
const std::string& fontFile, //必須爲字體文件(如”*.ttf”)
float fontSize,
const Size& dimensions,
TextHAlignment hAlignment,
TextVAlignment vAlignment
);
(3)createWithCharMap
Label::createWithCharMap(const std::string& charMapFile, int itemWidth,
int itemHeight, int startCharMap);

(4)createWithBMFont
Label::createWithBMFont(
const std::string& bmfontFilePath, //字體文件.font
const std::string& text, //內容
const TextHAlignment& alignment ,
int maxLineWidth = 0,
const Vec2& imageOffset //字符圖片的起始左上角座標。一般不要設置這個參數,因爲座標的配置均已在.font裏完成
);

2、Menu和MenuItems

菜單Menu是專門用來承載菜單按鈕的Layer圖層,圖層中的子節點只能夠是菜單項MenuItem或其子類。通常先創建菜單項MenuItem,然後使用一個或多個菜單項生成菜單Menu,最後把Menu加入當前Layer圖層。
由於CCMenu的父類爲Layer,所以錨點爲(0,0),且無法設置錨點。Menu的默認原點座標爲屏幕正中心
MenuItem是添加在Menu層中的,所以MenuItem的位置是相對於Menu層的偏移位置。MenuItem相對於Menu的偏移量默認爲(0,0),且菜單項的錨點默認爲(0.5,0.5)。

作爲其它菜單項的父類,主要提供了一下三個功能:

(1)提供了基本按鈕的狀態:正常、選中、禁用。
(2)爲按鈕實現了基本的回調函數機制。當玩家點積按鈕後,就會調用執行相應的回調函數。
(3)觸碰菜單項,附有自動放大效果。

菜單項的子類可以分成三類,總共六個:

(1)文字菜單項:MenuItemLabel、MenuItemAtlasFont、MenuItemFont;
(2)圖片菜單項:MenuItemSprite、MenuItemImage;
(3)切換菜單項:MenuItemToggle。

3、Button

(1) 創建Button
Button::create(
const std::string &normalImage,//正常狀態的紋理貼圖
const std::string& selectedImage , //選中狀態的紋理貼圖
const std::string& disableImage, // 禁用狀態的紋理貼圖
TextureResType texType
);

(2)監聽事件
void addTouchEventListener(const ccWidgetTouchCallback& callback);

4、RadioButton

(1) 創建RadioButton
RadioButton* create(
const std::string& backGround,
const std::string& cross,
TextureResType texType );

(2)監聽事件
void addEventListener (const ccRadioButtonCallback &callback)

	m_radioButtonGroup = RadioButtonGroup::create();
	this->addChild(m_radioButtonGroup);
	static const int NUMBER_OF_BUTTONS = 5;
	int startPosX = 40;
	for (int i = 0; i < NUMBER_OF_BUTTONS; ++i)
	{
		RadioButton* radioButton = RadioButton::create("radio_button_off.png", "radio_button_on.png");
		float posX = startPosX + 50 * i;
		radioButton->setPosition(Vec2(100, posX));
		radioButton->setScale(1.2f);
		m_radioButtonGroup->addRadioButton(radioButton);
		radioButton->addEventListener(CC_CALLBACK_2(xxxx::OnRadioButtonClicked, this));
		layerx->addChild(radioButton);
	}

void xxxx::OnRadioButtonClicked(RadioButton* radioButton, cocos2d::ui::RadioButton::EventType type)
{
	if (cocos2d::ui::RadioButton::EventType::SELECTED == type)
	{

		log("OnRadioButtonClicked SELECTED");
	}
	else
	{
		log("OnRadioButtonClicked UNSELECTED");
	}
}

5、CheckBox

CheckBox就是複選框,大家應該都見過複選框,它有兩個狀態,一個勾選態,一個非勾選態,通過CheckBox在這兩個狀態間的切換來實現一些特定的判斷功能,比如是否關閉音效等。

(1)創建CheckBox
CheckBox* create(
const std::string& backGround,
const std::string& backGroundSelected,
const std::string& cross,
const std::string& backGroundDisabled,
const std::string& frontCrossDisabled,
TextureResType texType );

CheckBox* create(
const std::string& backGround,
const std::string& cross,
TextureResType texType)

(2)CheckBox監聽事件

void addEventListenerCheckBox(Ref* target,SEL_SelectedStateEvent selector);

m_pCheckbox = CheckBox::create("check_box_normal.png",
									"check_box_normal_press.png",
									"check_box_active.png",
									"check_box_normal_disable.png",
									"check_box_active_disable.png");
	m_pCheckbox->setPosition(Vec2(sz.width/2, sz.height/2));

	m_pCheckbox->addEventListener(CC_CALLBACK_2(xxxxxx::OnCheckBoxSelectedEvent, this));

void xxxxxx::OnCheckBoxSelectedEvent(Ref* pSender, CheckBox::EventType type)
{
	switch (type)
	{
	case CheckBox::EventType::SELECTED:
		log("Selected");
		break;

	case CheckBox::EventType::UNSELECTED:
		log("Unselected");
		break;

	default:
		break;
	}

}

6、LoadingBar

一般作爲進度條,可以用來表示血量等。

(1)創建LoadingBar
static LoadingBar * create ()
創建一個空的LoadingBar。

static LoadingBar * create (
const std::string &textureName, //背景紋理圖片文件。
float percentage=0//顯示的進度百分比。
)
使用一個紋理和一個進度百分比創建一個LoadingBar。

static LoadingBar * create (
const std::string &textureName, //LoadingBar背景紋理圖片文件。
TextureResType texType, //LoadingBar背景紋理類型。
float percentage=0//顯示的進度百分比。
)
使用一個紋理、紋理類型和一個進度百分比創建一個LoadingBar。

	m_loadingBar = LoadingBar::create("sliderProgress.png");
	m_loadingBar->setPosition(Vec2(10, 50));
	m_loadingBar->setDirection(LoadingBar::Direction::LEFT);
	m_loadingBar->setContentSize(Size(200, 30));
m_loadingBar->setPercent(100);

(2)事件監聽
void addTouchEventListener(const ccWidgetTouchCallback& callback);

loadingBar->addTouchEventListener([=](Ref* sender, Widget::TouchEventType type){
  if (type == Widget::TouchEventType::ENDED) {
    if (loadingBar->isScale9Enabled())
    {
      loadingBar->setScale9Enabled(false);
    }
    else
      loadingBar->setScale9Enabled(true);
    }
});

7、Slider

(1)創建Slider

Slider* create();

Slider* create(
const std::string& barTextureName,
const std::string& normalBallTextureName,
TextureResType resType = TextureResType::LOCAL);

(2)綁定事件
void addEventListener(const ccSliderCallback& callback);

	m_slider = Slider::create();
	m_slider->loadBarTexture("sliderTrack.png");
	m_slider->loadSlidBallTextures("sliderThumb.png", "sliderThumb.png", "");
	m_slider->loadProgressBarTexture("sliderProgress.png");
	m_slider->setMaxPercent(10000);
	m_slider->setPosition(Vec2(sz.width / 3, sz.height / 2));
	m_slider->addEventListener(CC_CALLBACK_2(xxxxx::OnSliderEvent, this));

void xxxxx::OnSliderEvent(Ref *pSender, Slider::EventType type)
{
	if (type == Slider::EventType::ON_PERCENTAGE_CHANGED)
	{
		Slider* slider = dynamic_cast<Slider*>(pSender);
		int percent = slider->getPercent();
		int maxPercent = slider->getMaxPercent();
		log("Percent %f", 10000.0 * percent / maxPercent);
	}
}

8、Text 和 RichText

(1) 創建

Text* Text::create(const std::string& textContent,
const std::string& fontName,
float fontSize);
RichText* RichText::create();
RichText* RichText::createWithXML(const std::string& xml, const ValueMap& defaults = ValueMap(), const OpenUrlHandler& handleOpenUrl = nullptr);

(2) 代碼

Text

Text* alert = Text::create("RichText Demo", "Arial", 20);
	alert->setColor(Color3B(159, 168, 176));
	alert->setPosition(Vec2(sz.width / 2, sz.height - alert->getContentSize().height * 2));
	layerx->addChild(alert);

RichText

	m_richText = RichText::create();
	m_richText->ignoreContentAdaptWithSize(false);
	m_richText->setContentSize(Size(sz.width, 100));

	std::string str1 = "1";
	std::string str2 = "2";

	RichElementText* re1 = RichElementText::create(1, Color3B::WHITE, 255, "str1", "SimSun", 20);
	RichElementText* re2 = RichElementText::create(2, Color3B::YELLOW, 255, "And this is yellow. ", "Helvetica", 10);
	RichElementText* re3 = RichElementText::create(3, Color3B::RED, 255, "str2", "SimSun", 30);
	m_richText->pushBackElement(re1);
	m_richText->insertElement(re2, 1);
	m_richText->pushBackElement(re3);
	m_richText->setPosition(Vec2(sz.width / 3, sz.height / 2));
	layerx->addChild(m_richText);

9、定時器schedule

cocos2dx中有三種定時器:schedule,scheduleUpdate,scheduleOnce。
(1)scheduleUpdate
void scheduleUpdate(int handler, int priority);
加入當前節點後,程序會每幀都會自動執行一次默認的Update函數。(注:一定是Update函數哦,若想調用其他自己命名的函數則使用schedule)

(2)schedule
void schedule(SEL_SCHEDULE selector, float interval);
可以隔幾秒執行某個自定義的函數,

(3)scheduleOnce
void scheduleOnce(SEL_SCHEDULE selector, float delay);
在幾秒之後執行,並且只會執行一次。

(4)停止定時器
void unschedule(SEL_SCHEDULE selector);
void unscheduleUpdate(void);
void unscheduleAllCallbacks();

10、實戰分享

下載實戰結果

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章