实现滑动屏幕与底层滑动指标适配

首先是封装好的滑动指标类,具体首先创建一个画图类: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

实现滑动屏幕与底层滑动指标适配的相关文章

移动应用滑动屏幕方向判断解决方案,JS判断手势方向

问题分类 滑动屏幕打开相应功能操作. 问题描述 1.用户手动滑动屏幕,根据滑动的方向,打开相应的功能(如:向上滑摇钱树经验明细,向下滑打开任务明细,向左滑打开聚宝盆物品查看等功能),滑动事件捕获问题. 2.大家都知道,划动都有角度问题,如:向330度方向滑动手机,要计算出它的方向问题. 3.HTML5提供的滑动事件,只能读取到起点和终点坐标,计算角度问题. 4.手机屏幕坐标与标准坐标系转换问题. 解决方案 1.滑动屏幕事件使用HTML5 的touchstart滑动开始事件和touchend滑动结

移动端表层div滑动,导致底层body滑动(touchmove的阻止)

body很长,可以滑动,body头部有一个模拟下拉的选择框,下拉选择有滚动轴 我给body一个overflow:hidden和高度是没有用的.手机网站上背景还是可以滑动,然后我给body一个touchmove的preventdefault()阻止事件,body滑动阻止了,PC上面是可以了,但是手机上面滑动div还是会导致底部body的滑动,我给div 一个阻止冒泡的事件stopPropagation(),手机网站上面还是不可以. 解决方案 我经过反复测试,发现滚动轴滚到底部的时候,会触发body

javascript判断移动应用手势滑动屏幕方向

方案思路: 1.滑动屏幕事件使用HTML5 的 touchstart 滑动开始事件和 touchend 滑动结束事件. 2.方向的判断,以起点做平面坐标系,与终点连线做直线,直线与x正半轴计算角度:我们以45度角为方向分割线,如:只要滑动角度大于等于45度且小于135度,则判断它方向为向上滑. 3.使用Math.atan2()来计算起点与终点形成的直线角度. 4.仔细对比标准坐标系与屏幕坐标系,我们发现,标准坐标系,上半轴为负值,要实现转换,只需要调换Y坐标起点与终于位置即可. 代码实现: [网

Android上下左右滑动,显示底层布局

转载博客地址:http://www.cnblogs.com/flyme2012/p/4106308.html 闲着没事做了一个小东西.Android的上下左右滑动,显示底层布局.可以做类似于QQ消息列表的删除功能. 看效果: 实现基本原理: 前段时间学习了一下ViewDragHelper类,大概的就是通过这个类来控制的上下左右的滑动,方便的很多啊,也是很简单的代码,可以参考 我之前的关于ViewDragHelper的博客文章,这里面主要做的工作就是对触摸事件的传递,需要将触摸事件传递给底层的布局

Android监测手指上下左右滑动屏幕

在开发android程序时,有时会需要监测手指滑动屏幕,当手指朝上下左右不同方向滑动时做出不同的响应,那怎么去实现呢? 利用Android提供的手势监测器就可以很方便的实现,直接上代码(已测试通过) public class CbMainActivity extends Activity implements android.view.GestureDetector.OnGestureListener { //定义手势检测器实例 GestureDetector detector; @Overri

Android 播放电影时滑动屏幕调整屏幕亮度(转)

(转自:http://blog.csdn.net/piaozhiye/article/details/6544450) 发现有一些主流的播放器播放电影时可以通过滑动屏幕调整屏幕亮度,其实实现起来也很容易. 主要根据滑动的方向来设置屏幕亮度,以下这个demo实现向上滑动屏幕变亮,向下滑动则屏幕变暗.当的屏幕达到最亮或最暗(20%)的时候,设备会震动,代码简单,不多说. 同时设备震动需要有权限 <uses-permission android:name="android.permission.

手指滑动屏幕原理

//手指按下屏幕的点,抬起手指的点,按下的时间,抬起的时间 var startPoint=0; endPoint=0; startTime=0;   endTime=0; //touchstart事件 $(".xx").on("touchstart",function(event){ //每次重新滑动要清除上一次手指抬起的位置和时间 endPoint=0; endtime=0; startPoint=event.touches[0].clientY; startTi

RobotFramework:App滑动屏幕

转自:http://blog.csdn.net/jgw2008/article/details/77993399 在使用Robot Framework测试Android机器过程中, 经常要用到滚屏操作, 改如何实现这个效果呢? 其中一个方法, 就是使用关键字"Swipe", 这个关键字的效果类似模拟操作人员滑动屏幕的效果, 它有5个参数 ----start_x: 滑动开始的X坐标; ----start_y: 滑动开始的Y坐标; ----end_x: 滑动结束的X坐标; ----end_

swipe()滑动屏幕

屏幕页面滑动在APP自动化测试中属于一个比较常见也比较特殊的操作. 通过查看swipe()方法的源码可以知道它一共有5个参数,分别为: start_x:起点横坐标 start_y:起点纵坐标 end_x:终点横坐标 end_y:终点纵坐标 duration:滑动时间,单位毫秒 并且可以发现,它的本质其实是一个链式调用,从起点位置滑到终点位置,滑动时间为duration. 既然我们要使用,那肯定要给它传递坐标的参数, 那么起点坐标和终点坐标的位置怎么获得呢? 我们可以通过屏幕尺寸计算得到合适的坐标