直接上代码:
HelloWorldScene.cpp
#include "HelloWorldScene.h" USING_NS_CC; #define COIN_WIDTH 212 //coin 图片宽度 #define COIN_GAP 100 //间隔 #define COIN_COUNT 11 //个数 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(); //XKPageView::create(Size size,XKPageViewDelegate *delegate) pageView = XKPageView::create(Size(visibleSize.width,COIN_WIDTH),this); pageView -> setDirection(ScrollView::Direction::HORIZONTAL); //container 定位在屏幕中间 pageView -> setPosition(Point((visibleSize.width - COIN_WIDTH) * 0.5,(visibleSize.height - COIN_WIDTH) * 0.5)); addPages(); //设置裁切为false,这样layer 溢出pageView的Size还能显示 pageView -> setClippingToBounds(false); this -> addChild(pageView); //设置pageView 自动调整时的callback,可以在这里写你要的功能 pageView -> adjustCallback = [](XKPageView *pageView){ FiniteTimeAction *fadeIn = FadeTo::create(0.15,255); FiniteTimeAction *fadeOut = FadeTo::create(0.15,255 * 0.3); FiniteTimeAction *scaleToBig = ScaleTo::create(0.15,1.5f); FiniteTimeAction *scaleToSmall = ScaleTo::create(0.15,1.0f); Spawn *spawnIn = Spawn::createWithTwoActions(fadeIn,scaleToBig); Spawn *spawnOut = Spawn::createWithTwoActions(fadeOut,scaleToSmall); int current = pageView -> getCurrentIndex(); auto sprite = (Sprite*) pageView -> getPageAtIndex(current); sprite -> runAction(spawnIn); sprite = (Sprite *)pageView -> getPageAtIndex(current - 1); if (sprite !=NULL){ sprite -> runAction(spawnOut); } sprite = (Sprite *)pageView -> getPageAtIndex(current + 1); if (sprite !=NULL){ sprite -> runAction(spawnOut -> clone()); } }; return true; } void HelloWorld::addPages() { Size coinSize = Sprite::create("coin.png") -> getContentSize(); //11个layer 加到layer 上 for (int i = 0; i < COIN_COUNT; i++) { auto sprite = Sprite::create("coin.png"); sprite -> setPosition(coinSize.width * 0.5,coinSize.height * 0.5); std::string str = StringUtils::format("%d",i); Label *label = Label::createWithSystemFont(str,"Arial",60); label -> setTextColor(Color4B(0,255)); Size size = sprite -> getContentSize(); label -> setPosition(size.width * 0.5,size.height * 0.5); sprite -> addChild(label); //注意这里使用的时XKPageView 的addPage,不是addChild pageView -> addPage(sprite); } } Size HelloWorld::sizeForPerPage() { //Delegate 的东西,返回每个Page 的Size return Size(COIN_WIDTH + COIN_GAP,COIN_WIDTH); } void HelloWorld::pageViewDidScroll(XKPageView *pageView) { //监听滚动时间,可以再这里写滚动时候要添加的代码,比如缩放~ Size visibleSize = Director::getInstance() -> getVisibleSize(); float midX = visibleSize.width / 2; float offsetX = pageView -> getContentOffset().x; float tmp = COIN_WIDTH / 2.0f; float scale = 1.5; scale = scale - 1; for (int i = 0; i < COIN_COUNT; i++) { auto sprite = (Sprite *) pageView -> getPageAtIndex(i); float positionX = sprite -> getPositionX(); //转换成相对屏幕坐标 float endX = positionX + offsetX + midX - tmp; if (0 < endX && endX <= midX) { float x = endX / midX * scale + 1; sprite -> setScale(x); x = (endX / midX * 0.7 + 0.3) * 255; sprite -> setOpacity(x); }else if(endX > midX && endX < visibleSize.width){ float tmp2 = endX - midX; tmp2 = midX - tmp2; float x = tmp2 / midX * scale + 1; sprite -> setScale(x); x = (tmp2 / midX * 0.7 + 0.3) * 255; sprite -> setOpacity(x); }else { sprite -> setScale(1.0f); sprite -> setOpacity(255 * 0.3); } } } void HelloWorld::onEnter() { Layer::onEnter(); pageView -> adjustCallback(pageView); }
#ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE_H__ #include "cocos2d.h" #include "extensions/cocos-ext.h" #include "XKPageView.h" USING_NS_CC_EXT; class HelloWorld : public cocos2d::Layer,public XKPageViewDelegate { 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(); // implement the "static create()" method manually CREATE_FUNC(HelloWorld); // PageViewDelegate virtual Size sizeForPerPage(); virtual void pageViewDidScroll(XKPageView *pageView); private: XKPageView *pageView; void addPages(); public: virtual void onEnter(); }; #endif // __HELLOWORLD_SCENE_H__
XKPageView.h
// // XKPageView.h // XKPageView // // Created by Joueu on 14-11-26. // // #ifndef __XKPageView__XKPageView__ #define __XKPageView__XKPageView__ #include "cocos2d.h" #include "extensions/cocos-ext.h" USING_NS_CC; USING_NS_CC_EXT; class XKPageView; class XKPageViewDelegate { public: virtual ~XKPageViewDelegate(){}; XKPageViewDelegate(){}; //获取Page大小 virtual Size sizeForPerPage() = 0; //滚动回调 virtual void pageViewDidScroll(XKPageView *pageView){}; }; class XKPageView:public ScrollView { public: static XKPageView *create(Size size,XKPageViewDelegate *delegate); virtual bool init(Size size,XKPageViewDelegate *delegate); public: void setPageSize(Size size); virtual void setContentOffsetInDuration(Vec2 offset,float dt); virtual void setContentOffset(Vec2 offset); private: void performedAnimatedScroll(float dt); int current_index; float current_offset; //调整offset 的函数 void adjust(float offset); Size pageSize; CC_SYNTHESIZE(XKPageViewDelegate *,_delegate,Delegate); public: int pageCount; void addPage(Node *node); Node *getPageAtIndex(int index); int getCurrentIndex(); //滚动后调整回调 std::function<void(XKPageView *)> adjustCallback; }; #endif /* defined(__XKPageView__XKPageView__) */
// // XKPageView.cpp // XKPageView // // Created by Joueu on 14-11-26. // // #include "XKPageView.h" #define XKPAGEVIEW_TAG 10086 XKPageView *XKPageView::create(Size size,XKPageViewDelegate *delegate) { XKPageView *page = new XKPageView(); if (page && page -> init(size,delegate)) { page -> autorelease(); }else { CC_SAFE_RELEASE(page); } return page; } bool XKPageView::init(Size size,XKPageViewDelegate *delegate) { if (!ScrollView::initWithViewSize(size)) { return false; } //必须有delegate,否则断掉 CCASSERT(delegate,"delegate should not be NULL!"); setDelegate(delegate); if (_delegate) { //获取page的大小 pageSize = _delegate -> sizeForPerPage(); } //init Data pageCount = 0; current_index = 0; this -> setTouchEnabled(false); auto listener = EventListenerTouchOneByOne::create(); listener -> onTouchBegan = [&](Touch *touch,Event *event){ _dragging = false; this -> scheduleUpdate(); if (_direction == ScrollView::Direction::HORIZONTAL) { current_offset = this -> getContentOffset().x; }else { current_offset = this -> getContentOffset().y; } return true; }; listener -> onTouchMoved = [&](Touch *touch,Event *event){ float start,end; if (_direction == ScrollView::Direction::HORIZONTAL) { start = touch -> getStartLocation().x; end = touch -> getLocation().x; }else { start = touch -> getStartLocation().y; end = touch -> getLocation().y; } float offset = end - start; // * 2的作用是调节滚动速度,需要调滑动速度的 可以改这个值 if (_direction == ScrollView::Direction::HORIZONTAL) this -> setContentOffset(Vec2(current_offset + offset * 2,0)); else this -> setContentOffset(Vec2(0,current_offset + offset * 2)); }; listener -> onTouchEnded = [&](Touch *touch,Event *event){ float start = current_offset,end; if (_direction == ScrollView::Direction::HORIZONTAL) { end = this -> getContentOffset().x; }else { end = this -> getContentOffset().y; } float offset = end - start; this -> adjust(offset); _dragging = true; }; Director::getInstance() -> getEventDispatcher() -> addEventListenerWithSceneGraPHPriority(listener,this); return true; } void XKPageView::adjust(float offset) { Vec2 vec; float xOrY; if (_direction == ScrollView::Direction::HORIZONTAL) { vec = Vec2(-( current_index * (pageSize.width)),0); xOrY = pageSize.width; }else { vec = Vec2(0,-( current_index * (pageSize.height))); xOrY = pageSize.height; } //小于50回到原来位置 if (abs(offset) < 50){ this -> setContentOffsetInDuration(vec,0.15f); return; } int i = abs(offset / (xOrY)) + 1; if (offset < 0) { current_index += i; }else { current_index -= i; } if (current_index < 0) { current_index = 0; }else if(current_index > 10){ current_index = 10; } if (_direction == ScrollView::Direction::HORIZONTAL) { vec = Vec2(-( current_index * (pageSize.width)),0); }else { vec = Vec2(0,-( current_index * (pageSize.height))); } this -> adjustCallback(this); this -> setContentOffsetInDuration(vec,0.15f); } void XKPageView::setContentOffset(Vec2 offset) { ScrollView::setContentOffset(offset); if (_delegate != nullptr) { _delegate -> pageViewDidScroll(this); } } void XKPageView::setContentOffsetInDuration(Vec2 offset,float dt) { ScrollView::setContentOffsetInDuration(offset,dt); this->schedule(schedule_selector(XKPageView::performedAnimatedScroll)); } void XKPageView::performedAnimatedScroll(float dt) { if (_dragging) { this->unschedule(schedule_selector(XKPageView::performedAnimatedScroll)); this -> unscheduleUpdate(); return; } if (_delegate != nullptr) { _delegate -> pageViewDidScroll(this); } } void XKPageView::addPage(Node *node) { if (_direction == ScrollView::Direction::HORIZONTAL) { node -> setPosition(Point(pageCount * pageSize.width + node -> getPositionX(),node -> getPositionY())); this -> setContentSize(Size((pageCount + 1) * pageSize.width,pageSize.height)); }else { node -> setPosition(Point(node -> getPositionX(),pageCount * pageSize.height + node -> getPositionY())); this -> setContentSize(Size(pageSize.width,(pageCount + 1) *pageSize.height)); } node -> setTag(pageCount + XKPAGEVIEW_TAG); _container -> addChild(node); pageCount ++; } Node *XKPageView::getPageAtIndex(int index) { if (index < pageCount && index >= 0) { return _container -> getChildByTag(index + XKPAGEVIEW_TAG); } return NULL; } int XKPageView::getCurrentIndex() { return current_index; }
文章转自: http://helkyle.tk/cocos-2dx-3xPageView/