Cocos2d-js : 模拟IOS时间选择器

Cocos2d-js : 模拟IOS时间选择器,第1张

概述使用引擎:cocos2d-js 3.0 使用语言:javascript 运行平台:手机web --------------------------------------------------------------- 初步分析: *** 作过程:           滑动,转动,放缓速度,平衡,停止。 时间选择器的功能分析:         1. 滑动         2. N个选项结果(eg. 0


使用引擎:cocos2d-Js 3.0

使用语言:JavaScript

运行平台:手机web

---------------------------------------------------------------

初步分析:

*** 作过程:

滑动,转动,放缓速度,平衡,停止。

时间选择器的功能分析:

1. 滑动

2. N个选项结果(eg. 0~10)

3. 部分数字可见

4. 根据最近原则,自动平衡到结果item

5. ...

--------------------------------------------------------------------

于是我们立刻面临两种选择,一种是继承ScrollVIEw的做法,一种是使用ClipPingNode自己造轮子。

我们如果选择继承的做法,那么无疑工作量会比较多(修改ScrollVIEw逻辑流程)。

其实循环滚动的逻辑一点也不复杂,我们没必要去使用任何已有的滑动类控件,无论是扩展性还是运行效率,这个轮子自己造才是最好的选择。

那么我们使用ClipPingNode?

不是!而是使用ccui::Layout。最终我选择它的原因是,它不需要设置stencil,直接一句话即可设置成为裁剪(setClipPingEnabled),减少子父节点坐标计算的复杂性。


--------

UI如下:

--------


--------

核心点:

--------

1. 鉴于效率和方便性,使用一个contentNode来管理所有item。

2. 通过_bMoveing和_btouching标识来处理触摸和移动之间相互影响。

3. 循环滚动的实现逻辑:向上移动,那么最上的item会移动到最下,向下则反之。

4. 在 *** 作结束之后,做矫正平衡(准确移动到固定的位置)。


--------

代码实现:

--------

/** * Created by xxf on 12/19/2014. * *  1. touchTime < 0.3 s 判定为加速 *  2. 平衡性判断 *  3. 平衡后停止 *   * *  eg: * *   var List = ["1","2","3","4","5","6","7","8","9","10"];     var deFinition = {                size:cc.size(60,125),items:List,backGround: res.back            };     var node = new ScrollSelector(deFinition); */var ScrollSelector = ccui.Layout.extend({    _visibleClipNumber:3,// 同时显示Item的个数    _veLocity:3,// 速率    _timelimit:0.5,// 时间限制    _distancelimit:500,// 距离限制    _timeCondition:0.3,// 时间条件    _distanceCondition:30,// 距离条件    _diffY:0,_diffYCount:0,// 周期性计数,y轴的移动距离    _onceDiffYCount:0,// 一次触摸y轴的移动距离    _timeCount:0,// 触摸时间计时    _runningAction:null,_List:null,// item列表,用来平衡坐标    _originList:null,_currentItemIndex:2,// 目前是第几个item    _value:null,// 当前item的value    _beginPos:null,_contentNode:null,_backGround:null,_bMoveing:false,_btouching:false,_bBeginCountTime:false,_Fontcolor: cc.color.BLACK,_FontSize: 40,_Fontname: "Arial",// _mode:null,//游戏类型:选择器,游戏器    ctor: function (params) { //params 参数列表: items,textures.back,size        this._super();        this.setClipPingEnabled(true);        this.setContentSize(params.size);        this.setAnchorPoint(cc.p(0.5,0));        this.ignoreAnchor = false;        this._backGround = new cc.Sprite(params.backGround);        this.addChild(this._backGround);        this._backGround.x = this.wIDth/2;        this._backGround.y = this.height/2;        this._contentNode = new cc.Node();        this._contentNode.setAnchorPoint(cc.p(0.5,0));        this.addChild(this._contentNode);        this._contentNode.setposition(cc.p(this.wIDth/2,0));        // 创建N个Item        this._List = [];        this._originList = [];        for(var i = 0; i < params.items.length; i++){            var text = ccui.Text.create(params.items[i],this._Fontname,this._FontSize);            text.setTextVerticalAlignment(cc.VERTICAL_TEXT_AlignmENT_CENTER);            text.getVirtualRenderer().setcolor(this._Fontcolor);            text.setTextAreaSize(cc.size(params.size.wIDth,params.size.height/3));            text.setposition(cc.p(0,i* text.height + text.height/2));            this._contentNode.addChild(text,1,i);            this._List.push(text);            this._originList.push(text);        }        this._value = this._originList[1].getString();        this._Lister = cc.EventListener.create({            swallowtouches: true,event: cc.EventListener.touch_ONE_BY_ONE,ontouchBegan:this._ontouchBegan,ontouchmoved:this._ontouchmoved,ontouchended:this._ontouchended        });        cc.eventManager.addListener(this._Lister,this);        this.scheduleUpdateWithPriority(0);        // init data        this._diffYCount = this._List[0].height;        this._beginPos = cc.p(0,0);        this._distancelimit = params.size.height*2 + Math.random()*50;    },update: function(dt){        if(!this._btouching && this._bMoveing){ // Action中的时候,计算偏移量            var diffY = this._contentNode.y - this._beginPos.y;            this._diffYCount = this._diffYCount + diffY;            this._beginPos = this._contentNode.getposition();        }        this._balance();        if(this._bBeginCountTime) this._timeCount = this._timeCount + dt;    },_ontouchBegan:function (touch,event) {        var target = event.getCurrentTarget();        if (!target.containstouchLocation(touch)) return false;        target._beginPos = touch.getLocation();        target._btouching = true;        target._bMoveing = false;        if (target._contentNode.isRunning())            target._contentNode.stopAction(target._runningAction);        // 开启滑动计时        target._bBeginCountTime = true;        target._timeCount = 0;        return true;    },_ontouchmoved:function (touch,event) {        // Move中的时候,计算偏移量        var target = event.getCurrentTarget();        var getPoint = touch.getLocation();        var diffY = getPoint.y - target._beginPos.y;        target._contentNode.y = target._contentNode.y + diffY;        target._beginPos = getPoint;        target._diffYCount = target._diffYCount + diffY;        target._onceDiffYCount = target._onceDiffYCount + diffY;    },_ontouchended:function (touch,event) {        var target = event.getCurrentTarget();        target._btouching = false;        // 计算滑动  计算距离  计算速度        if (/*Math.abs(target._onceDiffYCount) > target._distanceCondition &&*/ target._timeCount < target._timeCondition) {            if (target._contentNode.isRunning())  target._contentNode.stopAction(target._runningAction);            var distance = Math.round(target._onceDiffYCount*target._veLocity);            var time = target._timeCount * target._veLocity;            var pn = distance > 0 ? 1 : -1;            distance = Math.abs(distance) > Math.abs(target._distancelimit) ? pn * target._distancelimit: distance;            time = time < target._timelimit ? target._timelimit: time;            var move = cc.moveBy(time,distance);            target._runningAction = cc.sequence(move.easing(cc.easeSineOut()),cc.callFunc(target._bounceBalance,target));            target._runningAction = target._contentNode.runAction(target._runningAction);            target._beginPos = target._contentNode.getposition();            target._bMoveing = true;        }else{ // 如果不移动,那么直接做平衡            target._bounceBalance();        }        target._onceDiffYCount = 0;        target._timeCount = 0;        target._bBeginCountTime = false;    },containstouchLocation:function (touch) {        var getPoint = touch.getLocation();        var myRect = this.getBoundingBox();        return cc.rectContainsPoint(myRect,getPoint);    },_balance:function(){        if(this._diffYCount > this._List[0].height){            var topItem = this._List.pop();            topItem.y = this._List[0].y - this._List[0].height;            this._List.unshift(topItem);            this._diffYCount = this._diffYCount - this._List[0].height;        }else if (this._diffYCount < -this._List[0].height) {            var bottomItem = this._List.shift();            bottomItem.y = this._List[this._List.length-1].y + this._List[this._List.length-1].height;            this._List.push(bottomItem);            this._diffYCount = this._diffYCount + this._List[0].height;        }    },_bounceBalance:function(){        var itemHight = this._List[0].height;        var num = Math.round(this._contentNode.y%itemHight);        var distance = 0;        if ( num > 0){            distance = num > itemHight/2 ? itemHight-num : -num;        }else {            distance = num > -itemHight/2 ? -num : -(itemHight + num);        }        var action = cc.moveBy(0.2,distance).easing(cc.easeSineOut());        this._contentNode.runAction(cc.sequence(action,cc.callFunc(this._end,this)));    },_end: function(){        var num = Math.round(this._contentNode.y/this._List[0].height);        var num2 = -1 * (num % this._List.length);        if (num2 > 0){            this._currentItemIndex = num2 + 2;        }else if (num2 < 0){            this._currentItemIndex = this._List.length + num2 + 2;        }else{            this._currentItemIndex = 2;        }        if (this._currentItemIndex > this._List.length){            this._currentItemIndex = this._currentItemIndex % this._List.length;        }        this._value = this._originList[this._currentItemIndex-1].getString();        cc.log(this._value);    }});


----------------------------------

由于设置了每秒滑动距离的限制,因此代码在手机web平台几乎没有效率问题。

在Native平台可以放宽一点,让滑动更爽快~

最后,由于小弟知识水平有限,代码中有各种不规范的地方望各位大神们多多包含。

总结

以上是内存溢出为你收集整理的Cocos2d-js : 模拟IOS时间选择器全部内容,希望文章能够帮你解决Cocos2d-js : 模拟IOS时间选择器所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1027547.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-23
下一篇 2022-05-23

发表评论

登录后才能评论

评论列表(0条)

保存