首先是封装好的滑动指标类,具体首先创建一个画图类:SliderIndicator类,该类代码如下:
//SliderIndicator.h
#include "cocos2d.h"
#include "ui/CocosGUI.h"
USING_NS_CC;
class SliderIndicator:public ui::Layout
{
public:
CREATE_FUNC(SliderIndicator);
virtual bool init();
CC_SYNTHESIZE(Color4B, _circleColor, CircleColor);//使用CC_SYNTHESIZE设置绘制颜色
protected:
//参考之前文章介绍draw函数
void onDraw(const Mat4 &transform, bool transformUpdated);
void draw(Renderer *renderer, const Mat4 &transform, bool transformUpdated);
CustomCommand _customCommand;
};
//SliderIndicator.cpp
#include "SliderIndicator.h"
bool SliderIndicator::init()
{
bool bRet = false;
do {
CC_BREAK_IF(!ui::Layout::init());
bRet = true;
} while (0);
return bRet;
}
void SliderIndicator::draw(Renderer *renderer, const Mat4 &transform, bool transformUpdated)
{
_customCommand.init(_globalZOrder);
_customCommand.func = CC_CALLBACK_0(SliderIndicator::onDraw, this,transform,transformUpdated);
renderer->addCommand(&_customCommand);
}
void SliderIndicator::onDraw(const cocos2d::Mat4 &transform, bool transformUpdated)
{
//OpenGL设置
Director* director = Director::getInstance();
CCASSERT(nullptr != director, "Director is null when seting matrix stack");
director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW, transform);
//CC_SYNTHESIZE设置_circleColor
DrawPrimitives::setDrawColor4B(_circleColor.r, _circleColor.g, _circleColor.b, _circleColor.a);
//绘制实心圆点
DrawPrimitives::drawSolidCircle( Vec2(0,0), director->getWinSize().height / 130, CC_DEGREES_TO_RADIANS(90), 50, 1.0f, 1.0f);
//end draw
director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
}
然后根据滑动指标个数,创建SliderIndicatorLayout类,代码如下:
//SliderIndicator.h
#include "cocos2d.h"
#include "ui/CocosGUI.h"
USING_NS_CC;
class SliderIndicatorLayout:public ui::Layout
{
public:
CREATE_FUNC(SliderIndicatorLayout);
virtual bool init();
//添加指示圆点个数
void addIndicator(int num);
//选中的第几个
void changeIndicator(int index);
private:
Size winSize;
float radius;
};
//SliderIndicatorLayout.cpp
#include "SliderIndicatorLayout.h"
#include "SliderIndicator.h"
bool SliderIndicatorLayout::init()
{
bool bRet = false;
do {
CC_BREAK_IF(!ui::Layout::init());
setLayoutType(cocos2d::ui::Layout::Type::VERTICAL);
winSize = Director::getInstance()->getWinSize();
//设置每个滑动指标大小
radius = winSize.height / 130;
bRet = true;
} while (0);
return bRet;
}
void SliderIndicatorLayout::addIndicator(int num)
{
setSize(Size(radius * 2, radius*3 * num));
for (int i = 0 ; i < num; i++)
{
auto indicator = SliderIndicator::create();
indicator->setSize(Size(radius, radius));
indicator->setCircleColor(Color4B(255, 40, 255, 255));//CC_SYNTHESIZE
indicator->setTag(i);//设置Tag,便于以后获取,来改变滑动指标
addChild(indicator);
//设置相对布局,由于项目的需要,该处设置的是垂直布局,在HelloWorld中setRotation(-90),将其旋转
auto lp_indicator = ui::LinearLayoutParameter::create();
lp_indicator->setGravity(cocos2d::ui::LinearLayoutParameter::LinearGravity::TOP);
lp_indicator->setMargin(ui::Margin(0,radius * 2.0f,0,0));
if (i == 0)
{
lp_indicator->setMargin(ui::Margin(0, 0,0,0));
}
indicator->setLayoutParameter(lp_indicator);
}
changeIndicator(0);//默认是第一个滑动指标
}
void SliderIndicatorLayout::changeIndicator(int index)//改变选中的滑动指标
{
for (int i = 0; i < getChildren().size(); i++)
{
auto indicator = dynamic_cast<SliderIndicator*>(getChildByTag(i));//根据Tag获取滑动指标
indicator->setCircleColor(Color4B(93, 114, 123, 95));
if (i == index)
{
indicator->setCircleColor(Color4B(93, 114, 123, 225));//改变颜色即可
}
}
}
使用方法:
1、创建HelloWorld类
在HelloWorld类中创建SliderIndicatorLayout类,通过addIndicator()函数传入滑动指标个数;
2、在SliderIndicatorLayout类中addIndicator设置SliderIndicator的颜色、滑动指标个数,即可调用SliderIndicator类完成绘制圆点;
3、执行SliderIndicator中的draw和ondraw函数;具体实现可参看TestCpp函数
4、在HelloWorld中通过事件响应,执行changeIndicator()函数,即可完成滑动指标的切换;
HelloWorld类使用:
//HelloWorld.h
#include "cocos2d.h"
#include "cocos2d.h"
#include "SliderIndicatorLayout.h"
#include "ui/CocosGUI.h"
using namespace cocos2d::ui;
USING_NS_CC;
class HelloWorld : public cocos2d::Layer
{
public:
// there's no 'id' in cpp, so we recommend returning the class instance pointer
static cocos2d::Scene* createScene();
// Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
virtual bool init();
SliderIndicatorLayout* sliderIndicator;
// a selector callback
void menuCloseCallback(cocos2d::Ref* pSender);
void pageViewEvent(Ref *pSender, cocos2d::ui::PageView::EventType type);//PageView事件
// implement the "static create()" method manually
CREATE_FUNC(HelloWorld);
};
//HelloWorld.cpp
#include "HelloWorldScene.h"
#include "cocos2d.h"
#include "ui/CocosGUI.h"
#include "SliderIndicatorLayout.h"
using namespace cocos2d::ui;
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;
}
Size visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();
/
// 2. add a menu item with "X" image, which is clicked to quit the program
// you may modify it.
// add a "close" icon to exit the progress. it's an autorelease object
auto closeItem = MenuItemImage::create(
"CloseNormal.png",
"CloseSelected.png",
CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 ,
origin.y + closeItem->getContentSize().height/2));
// create menu, it's an autorelease object
auto menu = Menu::create(closeItem, NULL);
menu->setPosition(Vec2::ZERO);
this->addChild(menu, 1);
//创建PageView
auto pageView = PageView::create();
pageView->addEventListener(CC_CALLBACK_2(HelloWorld::pageViewEvent, this));//pageView事件
// pageView->setLayoutType(cocos2d::ui::Layout::Type::RELATIVE);
// pageView->setBackGroundColorType(ui::Layout::BackGroundColorType::SOLID);
// pageView->setBackGroundColor(Color3B::BLACK);
pageView->ignoreAnchorPointForPosition(false);
pageView->setAnchorPoint(Vec2(0.5, 0.5));
pageView->setSize(Size(visibleSize.width/2,visibleSize.height/2));
pageView->setPosition(Vec2(visibleSize.width/2, visibleSize.height/2));
// auto rp_pageView = RelativeLayoutParameter::create();
// rp_pageView->setAlign(RelativeLayoutParameter::RelativeAlign::CENTER_IN_PARENT);
// pageView->setLayoutParameter(rp_pageView);
// 增加4个page
for(int i = 0; i < 4; i++)
{
Layout* layout1 = Layout::create();
layout1->setSize(Size(visibleSize.width/2,visibleSize.height/2));
ImageView* imageView = ImageView::create("scrollviewbg.png");
imageView->setScale9Enabled(true);
imageView->setSize(Size(visibleSize.width, visibleSize.height));
imageView->setPosition(Point(layout1->getSize().width / 2, layout1->getSize().height / 2));
layout1->addChild(imageView);
//设置page内容
Text* label = Text::create(StringUtils::format("page %d",(i+1)), "fonts/Marker Felt.ttf", 30);
label->setColor(Color3B(92, 192, 192));
label->setPosition(Point(layout1->getSize().width / 2.0f, layout1->getSize().height / 2.0f));
layout1->addChild(label);
pageView->addPage(layout1);
}
addChild(pageView);
//创建滑动指标
sliderIndicator = SliderIndicatorLayout::create();
sliderIndicator->retain();
sliderIndicator->addIndicator(4);//传入个数函数
sliderIndicator->ignoreAnchorPointForPosition(false);
sliderIndicator->setAnchorPoint(Vec2::ANCHOR_MIDDLE);
sliderIndicator->setPosition(Vec2(visibleSize.width/2,100));
sliderIndicator->setRotation(-90);
addChild(sliderIndicator);
// auto rp_slider = ui::RelativeLayoutParameter::create();
// rp_slider->setAlign(cocos2d::ui::RelativeLayoutParameter::RelativeAlign::CENTER_IN_PARENT);
// sliderIndicator->setLayoutParameter(rp_slider);
return true;
}
void HelloWorld::pageViewEvent(cocos2d::Ref *pSender, cocos2d::ui::PageView::EventType type)
{
auto pageView = dynamic_cast<PageView*>(pSender);//获取当前页面
auto index = pageView->getCurPageIndex();//获取当前页面的index
switch (type)
{
case cocos2d::ui::PageView::EventType::TURNING:
{
sliderIndicator->changeIndicator(index);//根据page的index改变滑动指标
}
break;
default:
break;
}
}
void HelloWorld::menuCloseCallback(Ref* pSender)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
MessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");
return;
#endif
Director::getInstance()->end();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
exit(0);
#endif
}
执行效果如下: