首先是封装好的滑动指标类,具体首先创建一个画图类: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 }
执行效果如下:
实现滑动屏幕与底层滑动指标适配
时间: 2024-10-06 12:18:05