直接上代码:

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);
}


HelloWorldScene.h
#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.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/

使用cocos-2dx 3.x 封装的PageView的更多相关文章

  1. 用canvas做一个DVD待机动画的实现代码

    这篇文章主要介绍了用canvas做一个DVD待机动画的实现代码的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  2. html5录音功能实战示例

    这篇文章主要介绍了html5录音功能实战示例的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  3. H5 canvas实现贪吃蛇小游戏

    本篇文章主要介绍了H5 canvas实现贪吃蛇小游戏,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  4. ios – 属性类型’id’与从’UIToolbar’警告继承的类型’id’不兼容

    我刚刚安装了xcode5,现在我收到了这个警告.我以前从未见过它.我的应用运行良好,但我讨厌看到一个警告.有谁知道这是什么以及如何解决它?

  5. ios – 使用Swift 3.0附近的蓝牙设备

    )我只是使用函数内置的参数来提及它确实是一个IOBluetoothDevice对象,而且只是要求打印这些信息.最后的说明我希望在Swift中使用IOBluetooth时,我创建的这个Q/A可以帮助其他有需要的人.缺乏任何教程和大量过时的Objective-C代码使得查找此信息非常具有挑战性.我要感谢@RobNapier在一开始就试图找到这个谜题的答案的支持.我还要感谢NotMyName在AppleDeveloper论坛上对我的post的回复.我将在iOS设备中更早地探索这种用法!

  6. iOS将UIView转换为ScrollView而不破坏布局?

    是否有可能在不破坏所有约束和放置的情况下从UIView移动到UIScrollView.问题是我构建整个UI而不在iPhone4上测试它,现在我看到一些视图应该在ScrollView中工作.我尝试了一些技巧,但没有任何作用.约束被删除.以下是示例的示例图片:现在我希望test1UIView是ScrollView,我试图将ScrollView放在test1View中,然后在滚动视图中递归复制test1

  7. ios – 放大故事板中的任何视图时,Xcode 8.2和8.1崩溃

    当我单击视图框并拖动以放大视图时,视图不会放大.但相反,鼠标等待指示器将持续一秒钟,然后整个xcode将崩溃.这是在我的代码8.2更新后发生的.所以我尝试安装xcode8.1,问题仍然存在于一个特定项目中.所有其他项目都运作良好.故事板中没有警告或冲突.我不记得改变任何设置.附加崩溃日志:CRASH_LOG解决方法修正了问题:在我将ScrollView添加到ViewController并更改了Vi

  8. ios – UIButton在uiscrollView中不起作用

    我有一个将UIView作为子视图的scrollView.这有UIView子视图UIButton.只有scrollView连接到插座,其余全部都是代码.按钮不响应触摸,触摸时不变蓝.我能做些什么才能让它发挥作用?这是代码:解决方法您必须设置视图的内容大小.它必须大于或等于scrollView的内容大小.因为您的视图的默认大小是320*480和320*568.因此,增加视野的高度–self.view.frame=CGRectMake;然后将其添加为scrollView的子视图.将帮助您解决问题.

  9. ios – scrollViewDidEndDecelerating检测哪个集合视图在运行

    我使用这种方法来组织分页:当我滚动我的UICollectionView时,我在屏幕上更改了一些内容.但是我的屏幕上有很少的UICollectionView,我只需要一个.解决方法好吧,UICollectionView继承自UIScrollView,因此您可以检查哪个滚动视图最终从委托方法中减速.

  10. ios – 如何使用新的Apple Swift语言发布JSON

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

随机推荐

  1. 【cocos2d-x 3.x 学习笔记】对象内存管理

    Cocos2d-x的内存管理cocos2d-x中使用的是上面的引用计数来管理内存,但是又增加了一些自己的特色。cocos2d-x中通过Ref类来实现引用计数,所有需要实现内存自动回收的类都应该继承自Ref类。下面是Ref类的定义:在cocos2d-x中创建对象通常有两种方式:这两中方式的差异可以参见我另一篇博文“对象创建方式讨论”。在cocos2d-x中提倡使用第二种方式,为了避免误用第一种方式,一般将构造函数设为protected或private。参考资料:[1]cocos2d-x高级开发教程2.3节[

  2. 利用cocos2dx 3.2开发消灭星星六如何在cocos2dx中显示中文

    由于编码的不同,在cocos2dx中的Label控件中如果放入中文字,往往会出现乱码。为了方便使用,我把这个从文档中获取中文字的方法放在一个头文件里面Chinese.h这里的tex_vec是cocos2dx提供的一个保存文档内容的一个容器。这里给出ChineseWords,xml的格式再看看ChineseWord的实现Chinese.cpp就这样,以后在需要用到中文字的地方,就先include这个头文件然后调用ChineseWord函数,获取一串中文字符串。

  3. 利用cocos2dx 3.2开发消灭星星七关于星星的算法

    在前面,我们已经在GameLayer中利用随机数初始化了一个StarMatrix,如果还不知道怎么创建星星矩阵请回去看看而且我们也讲了整个游戏的触摸事件的派发了。

  4. cocos2dx3.x 新手打包APK注意事项!

    这个在编译的时候就可以发现了比较好弄这只是我遇到的,其他的以后遇到再补充吧。。。以前被这两个问题坑了好久

  5. 利用cocos2dx 3.2开发消灭星星八游戏的结束判断与数据控制

    如果你看完之前的,那么你基本已经拥有一个消灭星星游戏的雏形。开始把剩下的两两互不相连的星星消去。那么如何判断是GameOver还是进入下一关呢。。其实游戏数据贯穿整个游戏,包括星星消除的时候要加到获得分数上,消去剩下两两不相连的星星的时候的加分政策等,因此如果前面没有做这一块的,最好回去搞一搞。

  6. 利用cocos2dx 3.2开发消灭星星九为游戏添加一些特效

    needClear是一个flag,当游戏判断不能再继续后,这个flag变为true,开始消除剩下的星星clearSumTime是一个累加器ONE_CLEAR_TIME就是每颗星星消除的时间2.连击加分信息一般消除一次星星都会有连击信息和加多少分的信息。其实这些combo标签就是一张图片,也是通过控制其属性或者runAction来实现。源码ComboEffect.hComboEffect.cpp4.消除星星粒子效果消除星星时,为了实现星星爆裂散落的效果,使用了cocos2d提供的粒子特效引擎对于粒子特效不了

  7. 02 Cocos2D-x引擎win7环境搭建及创建项目

    官网有搭建的文章,直接转载记录。环境搭建:本文介绍如何搭建Cocos2d-x3.2版本的开发环境。项目创建:一、通过命令创建项目前面搭建好环境后,怎样创建自己的Cocos2d-x项目呢?先来看看Cocos2d-x3.2的目录吧这就是Cocos2d-x3.2的目录。输入cocosnew项目名–p包名–lcpp–d路径回车就创建成功了例如:成功后,找到这个项目打开proj.win32目录下的Hello.slnF5成功了。

  8. 利用cocos2dx 3.2开发消灭星星十为游戏添加音效项目源码分享

    一个游戏,声音也是非常的重要,其实cocos2dx里面的简单音效引擎的使用是非常简单的。我这里只不过是用一个类对所有的音效进行管理罢了。Audio.hAudio.cpp好了,本系列教程到此结束,第一次写教程如有不对请见谅或指教,谢谢大家。最后附上整个项目的源代码点击打开链接

  9. 03 Helloworld

    程序都有一个入口点,在C++就是main函数了,打开main.cpp,代码如下:123456789101112131415161718#include"main.h"#include"AppDelegate.h"#include"cocos2d.h"USING_NS_CC;intAPIENTRY_tWinMain{UNREFERENCED_ParaMETER;UNREFERENCED_ParaMETER;//createtheapplicationinstanceAppDelegateapp;return

  10. MenuItemImage*图标菜单创建注意事项

    学习cocos2dx,看的是cocos2d-x3.x手游开发实例详解,这本书错误一大把,本着探索求知勇于发现错误改正错误的精神,我跟着书上的例子一起调试,当学习到场景切换这个小节的时候,出了个错误,卡了我好几个小时。

返回
顶部