Cocos2d-x学习笔记(五)—— 常见UI界面(未完全)

前端之家收集整理的这篇文章主要介绍了Cocos2d-x学习笔记(五)—— 常见UI界面(未完全)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

对于UI界面,目前常用的有字体显示标签菜单,进度条,调度器,自定义文字按钮,自定义拖动进度条。(后续添加

我们的代码都是直接在新建项目HelloWorld中的HelloWorldScene.cpp的init()函数中操作。


字体和标签显示

<span style="font-size:18px;">CCSize s = CCDirector::sharedDirector()->getWinSize();

	// !!!!!字体以及标签!!!!!
	// 参数:1、要显示文字;2、显示字体;3、字体大小
	CCLabelTTF *ttf = CCLabelTTF::create("windows7lake","A Damn Mess.ttf",32);
	ttf->setPosition(100,s.height - 10);
	addChild(ttf);

	// 参数:1、要显示文字;2、显示字体;3、字体大小;4、尺寸(把这一段字符串看作整体,
	// 需要显示的大小);5、屏幕横向位置;6、屏幕纵向位置
	Label *ttf1 = Label::createWithSystemFont("windows7",42,Size::Size(70,40),TextHAlignment::CENTER,TextVAlignment::TOP);
	ttf1->setPosition(100,s.height - 60);
	addChild(ttf1);

	// 参数:1、要显示文字;2、显示字体的相对路径
	LabelBMFont *ttf2 = LabelBMFont::create("lake","fonts/bitmapFontChinese.fnt");
	ttf2->setPosition(50,s.height - 110);
	addChild(ttf2);

	// 参数:1、要显示文字;2、显示字体的相对路径;
	LabelAtlas *ttf3 = LabelAtlas::create("123 Test","fonts/tuffy_bold_italic-charmap.plist");
	ttf3->setPosition(50,s.height - 160);
	addChild(ttf3);

	// 参数:1、要显示文字;2、显示字体的相对路径;3、字体宽度;4、字体高度;5、字体图片中的起始符号(这里为空格)
	LabelAtlas *ttf4 = LabelAtlas::create("456 Test","fonts/tuffy_bold_italic-charmap.png",24,32,' ');
	ttf4->setPosition(50,s.height - 210);
	addChild(ttf4);

	// 字体配置参数:1、字体;2、字体大小
	TTFConfig config("fonts/arial.ttf",16);
	// 参数:1、字体配置;2、显示字符;3、相对横向位置
	Label *ttf5 = Label::createWithTTF(config,"789 test",TextHAlignment::RIGHT);
	ttf5->setPosition(50,s.height - 250);
	this->addChild(ttf5);

	// 参数:显示字体的相对路径
	Label *ttf6 = Label::createWithCharMap("fonts/tuffy_bold_italic-charmap.plist");
	addChild(ttf6);
	ttf6->setPosition(50,s.height - 290);</span>
运行结果:



菜单

<span style="font-size:18px;">CCSize s = CCDirector::sharedDirector()->getWinSize();
// !!!!!菜单!!!!!
	// Sprite Item
	auto spriteNormal = Sprite::create("image/HelloWorld.png",Rect(0,23 * 2,115,23));
	auto spriteSelected = Sprite::create("image/HelloWorld.png",23 * 1,23));
	auto spriteDisabled = Sprite::create("image/HelloWorld.png",23 * 0,23));
	MenuItemSprite *item1 = MenuItemSprite::create(spriteNormal,spriteSelected,spriteDisabled,CC_CALLBACK_1(HelloWorld::menuCallback,this));

	// Image Item
	MenuItemImage *item2 = MenuItemImage::create("CloseNormal.png","CloseSelected.png",this));

	// Font Item
	MenuItemFont *item3 = MenuItemFont::create("Lake",this));

	// Label Item
	LabelAtlas *labelAtlas = LabelAtlas::create("0123456789",16,'.');
	MenuItemLabel *item4 = MenuItemLabel::create(labelAtlas,this));

	Menu *menu = Menu::create(item1,item2,item3,item4,nullptr);
	menu->alignItemsVertically();
	menu->setPositionX(300);

	addChild(menu);</span>
运行结果:



进度条:

<span style="font-size:18px;">CCSize s = CCDirector::sharedDirector()->getWinSize();
// !!!!!进度条!!!!!
	Sequence *s1 = Sequence::createWithTwoActions(
		ProgressTo::create(4,100),ProgressTo::create(0,0));
	Sequence *s2 = Sequence::createWithTwoActions(
		ProgressTo::create(4,0));
	CCProgressTimer *pt1 = CCProgressTimer::create(Sprite::create("HelloWorld.png"));
	CCProgressTimer *pt2 = CCProgressTimer::create(Sprite::create("HelloWorld.png"));
// 设置旋转进度条
//pt1->setType(CCProgressTimer::Type::RADIAL);

	// 设置直线进度条
	pt1->setType(CCProgressTimer::Type::BAR);
	// 设置扩展的点
	pt1->setMidpoint(Vec2(1,0));
	// 设置x轴或y轴扩展
	pt1->setBarChangeRate(Vec2(1,0));

	pt1->setPosition(100,100);
	pt1->runAction(Repeat::create(s1,1));
	addChild(pt1);


	// 设置旋转进度条
	//pt2->setType(CCProgressTimer::Type::RADIAL);
	//// 设置反向旋转进度条
	//pt2->setReverseProgress(true);

	// 设置直线进度条
	pt2->setType(CCProgressTimer::Type::BAR);
	pt2->setMidpoint(Vec2(0,0));
	pt1->setBarChangeRate(Vec2(0,1));

	pt2->setPosition(s.width - 100,100);
	pt2->runAction(Repeat::create(s2,1));
	addChild(pt2);</span>

运行结果



调度器:

<span style="font-size:18px;">HelloWorldScene.h

void update(float dt) override;</span>
<span style="font-size:18px;">init()
{
// 随着游戏帧率不断输出,默认调用重载的update()函数
	//scheduleUpdate();

	// 参数:1、时间调度选择器,里面是回调函数;2、每次间隔时间;3、调用次数;
	// 4、第一次触发之前的延迟时间
	//schedule(schedule_selector(HelloWorld::update),1.0f,kRepeatForever,0);
	// 只调用一次,第二个参数为触发之前的延迟时间
	scheduleOnce(schedule_selector(HelloWorld::update),0.1f);
}
void HelloWorld::update(float dt)
{
	log("update");
}</span>

自定义文字按钮:

新建TextButton.h:

<pre name="code" class="cpp">#ifndef __TEXTBUTTON_H__
#define __TEXTBUTTON_H__

#include "cocos2d.h"
#include "ui/CocosGUI.h"
using namespace cocos2d;
using namespace cocos2d::ui;

class TextButton : public cocos2d::Label
{
public:
	// 创建按钮
	static TextButton *create(const std::string& text,const std::function<void(TextButton*)> &onTriggered);

	// 设置是否可以点击
	void setEnabled(bool enabled);
	CREATE_FUNC(TextButton);
	
private:
	// 触发器
	std::function<void(TextButton*)> _onTriggered;
	bool _enabled;

	TextButton();
	// 判断点击的点是否在按钮范围内
	bool touchHits(Touch* touch);

	bool onTouchBegan(Touch* touch,Event* event);
	void onTouchEnded(Touch* touch,Event* event);
	void onTouchCancelled(Touch* touch,Event* event);

	// 放大缩小按钮
	void ScaleButtonTo(float scale);
};

#endif // !__TEXTBUTTON_H__
 

TextButton.cpp:

#include "TextButton.h"

TextButton* TextButton::create(const std::string& text,const std::function<void(TextButton*)> &onTriggered)
{
	// 建立一个按钮对象
	auto ret = new (std::nothrow) TextButton();

	// 标签设置
	TTFConfig ttfconfig("fonts/arial.ttf",25);
	if (ret && ret->setTTFConfig(ttfconfig))
	{
		ret->setString(text);
		// 设置触发器
		ret->_onTriggered = onTriggered;
		// 自动释放
		ret->autorelease();

		return ret;
	}
	delete ret;
	return nullptr;
}

void TextButton::setEnabled(bool enabled)
{
	_enabled = enabled;
	if (_enabled)
	{
		this->setColor(Color3B::WHITE);
	}
	else
	{
		this->setColor(Color3B::GRAY);
	}
}

TextButton::TextButton() : _onTriggered(nullptr),_enabled(true)
{
	// 建立监听器并设置触摸监听
	auto listener = EventListenerTouchOneByOne::create();
	listener->setSwallowTouches(true);

	listener->onTouchBegan = CC_CALLBACK_2(TextButton::onTouchBegan,this);
	listener->onTouchEnded = CC_CALLBACK_2(TextButton::onTouchEnded,this);
	listener->onTouchCancelled = CC_CALLBACK_2(TextButton::onTouchCancelled,this);

	// 将监听加入发送器
	_eventDispatcher->addEventListenerWithSceneGraPHPriority(listener,this);
}

bool TextButton::touchHits(Touch* touch)
{
	// 将屏幕坐标转换为Cocos2d坐标(OpenGL坐标)
	auto hitPos = this->convertToNodeSpace(touch->getLocation());
	// 判断点击范围是否在文字按钮范围
	if (hitPos.x >= 0 && hitPos.y >= 0 && hitPos.x <= _contentSize.width
		&& hitPos.y <= _contentSize.height)
	{
		return true;
	}
	return false;
}

bool TextButton::onTouchBegan(Touch* touch,Event* event)
{
	auto hits = touchHits(touch);
	if (hits)
	{
		// 缩小按钮0.95倍
		ScaleButtonTo(0.95);
	}
	return hits;
}

void TextButton::onTouchEnded(Touch* touch,Event* event)
{
	if (_enabled) {
		auto hits = touchHits(touch);
		if (hits && _onTriggered)
		{
			// 为按钮添加触发器
			_onTriggered(this);
		}
	}
	ScaleButtonTo(1);
}

void TextButton::onTouchCancelled(Touch* touch,Event* event)
{
	ScaleButtonTo(1);
}

void TextButton::ScaleButtonTo(float scale)
{
	// 创建缩放动画
	auto action = ScaleTo::create(0.05f,scale);
	action->setTag(10000);
	stopActionByTag(10000);
	runAction(action);
}

自定义拖动进度条:

新建SliderProgress.h:

#ifndef __SLIDERPROGRESS_H__
#define __SLIDERPROGRESS_H__

#include "cocos2d.h"
#include "ui/CocosGUI.h"
using namespace cocos2d;
using namespace cocos2d::ui;

class SliderProgress : public Slider
{
public:
	enum class TouchEvent {
		DOWN,MOVE,UP,CANCEL
	};
	// 定义回调对象
	typedef std::function<void(SliderProgress*,float,TouchEvent)> ccSliderProgressCallBack;

	static SliderProgress* create();

	// 设置回调函数
	void setCallBack(const ccSliderProgressCallBack& callback);

	// 设置进度条进度
	void setRatio(float ratio);

	virtual bool onTouchBegan(Touch* touch,Event* unusedEvent) override;
	virtual void onTouchMoved(Touch *touch,Event *unusedEvent) override;
	virtual void onTouchEnded(Touch *touch,Event *unusedEvent) override;
	virtual void onTouchCancelled(Touch *touch,Event *unusedEvent) override;

private:
	// 触摸事件的类型
	TouchEvent _touchEvent;
	// 进度条的比率,范围0.0f-1.0f
	float _ratio;
	// 回调功能函数
	ccSliderProgressCallBack _callback;
};

#endif // !__SLIDERPROGRESS_H__

SliderProgress.cpp:

#include "SliderProgress .h"

SliderProgress* SliderProgress::create()
{
	auto ret = new (std::nothrow) SliderProgress();
	if (ret && ret->init())
	{
		ret->_callback = nullptr;
		// 将图片缓存到纹理缓存
		ret->loadBarTexture("slider/sliderTrack.png");
		ret->loadSlidBallTextures("slider/sliderThumb.png","slider/sliderThumb.png","");
		ret->loadProgressBarTexture("slider/sliderProgress.png");

		ret->autorelease();
		return ret;
	}
	CC_SAFE_DELETE(ret);
	return ret;
}

void SliderProgress::setCallBack(const ccSliderProgressCallBack& callback)
{
	_callback = callback;
}

void SliderProgress::setRatio(float ratio)
{
	if (ratio > 1.0f)
	{
		ratio = 1.0f;
	}
	else if (ratio < 0.0f)
	{
		ratio = 0.0f;
	}

	_ratio = ratio;
	_percent = 100 * _ratio;

	// 获得当前Slider移动图标点ball距离左边起点水平方向的长度
	float dis = _barLength*_ratio;
	// 设置移动图标点ball的位置
	_slidBallRenderer->setPosition(Vec2(dis,_contentSize.height / 2.0f));
	if (_scale9Enabled)
	{
		// 设置进度条的长度
		_progressBarRenderer->setPreferredSize(Size(dis,_progressBarTextureSize.height));
	}
	else
	{
		// 从先前加载的图片纹理缓存中取出图片精灵Slider进度条
		auto spriteRenderer = _progressBarRenderer->getSprite();

		if (nullptr != spriteRenderer)
		{
			// 返回精灵Slider进度条的边框矩形
			Rect rect = spriteRenderer->getTextureRect();
			// 从进度条缓存里面取出宽度*比率=矩形的宽度
			rect.size.width = _progressBarTextureSize.width * _ratio;
			// 设置精灵Slider进度条的边框矩形缓存
			spriteRenderer->setTextureRect(rect,spriteRenderer->isTextureRectRotated(),rect.size);
		}
	}
}

bool SliderProgress::onTouchBegan(Touch* touch,Event* unusedEvent)
{
	auto ret = Slider::onTouchBegan(touch,unusedEvent);
	if (ret &&_callback)
	{
		_touchEvent = TouchEvent::DOWN;
		// 将接受的坐标转换为本地坐标
		Vec2 nsp = convertToNodeSpace(_touchBeganPosition);
		_ratio = nsp.x / _barLength;
		if (_ratio < 0.0f) {
			_ratio = 0.0f;
		}
		else if (_ratio > 1.0f) {
			_ratio = 1.0f;
		}
		// 设置回调函数
		_callback(this,_ratio,_touchEvent);
	}
	return ret;
}

void SliderProgress::onTouchMoved(Touch *touch,Event *unusedEvent)
{
	_touchEvent = TouchEvent::MOVE;
	Slider::onTouchMoved(touch,unusedEvent);
	Vec2 nsp = convertToNodeSpace(_touchMovePosition);
	_ratio = nsp.x / _barLength;
	if (_ratio < 0.0f)
		_ratio = 0.0f;
	else if (_ratio > 1.0f)
		_ratio = 1.0f;
	if (_callback){
		_callback(this,_touchEvent);
	}
}

void SliderProgress::onTouchEnded(Touch *touch,Event *unusedEvent)
{
	_touchEvent = TouchEvent::UP;
	Slider::onTouchEnded(touch,unusedEvent);
	Vec2 nsp = convertToNodeSpace(_touchEndPosition);
	_ratio = nsp.x / _barLength;
	if (_ratio < 0.0f)
		_ratio = 0.0f;
	else if (_ratio > 1.0f)
		_ratio = 1.0f;
	if (_callback){
		_callback(this,_touchEvent);
	}
}

void SliderProgress::onTouchCancelled(Touch *touch,Event *unusedEvent)
{
	_touchEvent = TouchEvent::CANCEL;
	Slider::onTouchCancelled(touch,unusedEvent);

	if (_callback){
		_callback(this,_touchEvent);
	}
}

自定义控件的使用,HelloWorldScene.cpp:

#include "HelloWorldScene.h"
#include "TextButton.h"
#include "SliderProgress .h"

USING_NS_CC;

Scene* HelloWorld::createScene()
{
    // 'scene' is an autorelease object
    auto scene = Scene::create();
    
    // 'layer' is an autorelease object
    auto layer = HelloWorld::create();

    // add layer as a child to scene
    scene->addChild(layer);

    // return the scene
    return scene;
}

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
    //////////////////////////////
    // 1. super init first
	if (!Layer::init())
	{
		return false;
	}

	auto okbutton = TextButton::create("ok",[&](TextButton* textbutton){
		auto ttfLabel = LabelTTF::create("Are you sure?","arial.ttf",32);
		ttfLabel->setPosition(200,250);
		ttfLabel->setTag(1111);
		this->addChild(ttfLabel);
	});
	okbutton->setPosition(170,290);
	addChild(okbutton);
	auto cancellbutton = TextButton::create("cancell",[&](TextButton* textbutton){
		removeChildByTag(1111,true);
	});
	cancellbutton->setPosition(270,290);
	addChild(cancellbutton);

	label = Label::create("LAKE",50);
	label->setPosition(240,100);
	addChild(label);
	auto slider = SliderProgress::create();
	slider->setPercent(100);
	slider->setCallBack([&](SliderProgress* se,float ratio,SliderProgress::TouchEvent event) {
		label->setDimensions(150 * ratio,150 * ratio);
	});
	slider->setPosition(Vec2(240,200));
	addChild(slider);

    return true;
}

void HelloWorld::menuCloseCallback(Ref* pSender)
{
	Director::getInstance()->end();
}

运行结果:

猜你在找的Cocos2d-x相关文章