cocos-js,Widget的addTouchEventListener改善

原创 2016年05月30日 13:43:49

一、基本使用


addTouchEventListener是属于Widget下的触摸事件相关的操作,基本使用规则如下:

var button = new ccui.Button()
button.addTouchEventListener(this.touchEvent, this)

touchEvent: function (sender, type) {
    switch (type) {
        case ccui.Widget.TOUCH_BEGAN:
            this._topDisplayLabel.setString("Touch Down");
            break;

        case ccui.Widget.TOUCH_MOVED:
            this._topDisplayLabel.setString("Touch Move");
            break;

        case ccui.Widget.TOUCH_ENDED:
            this._topDisplayLabel.setString("Touch Up");
            break;

        case ccui.Widget.TOUCH_CANCELED:
            this._topDisplayLabel.setString("Touch Cancelled");
            break;

        default:
            break;
    }
}

二、为何改善


现在的触摸事件只做监听,并没有相关逻辑上的判断,我们游戏在开发的过程中遇到一些不正常点击而导致的问题。例如:在场景跳转的时候,连续点击两次后,会push两场同样的场景,正常逻辑应该是只push一次。

三、如何改善


先看我在基于原事件基础上添加的一些类型:

ccui.Widget.TOUCH_TYPE_TIMELY                    = 1  //及时:随时点击,随时响应
ccui.Widget.TOUCH_TYPE_DELAY_AFTER               = 2  //延时:随时点击,点击后马上响应,延时一段时间后,响应下次点击
ccui.Widget.TOUCH_TYPE_DELAY_FRONT               = 3  //延时:每次onEnter时,延时一段时间后,才能响应点击
ccui.Widget.TOUCH_TYPE_ONCE                      = 4  //一次:只有一次点击机会,点击后对象触摸禁止,当onExit后恢复
ccui.Widget.TOUCH_TYPE_ALL_BAN                   = 5  //所有:只有一次点击机会,点击后全屏触摸禁止,当onExit后恢复
ccui.Widget.TOUCH_TYPE_DELAY_FRONT_AND_ALL_BAN   = 11 //兼具:DELAY_FRONT和ALL_BAN

代码如下:

ccui.Widget.prototype.addTouch = function(_func,_type,_time){
    var __type = _type || ccui.Widget.TOUCH_TYPE_TIMELY
    var __time = _time || 1

    switch (__type){

        case ccui.Widget.TOUCH_TYPE_TIMELY:
            this.addTouchEventListener(_func)
            break

        case ccui.Widget.TOUCH_TYPE_DELAY_AFTER:
            //当触发点击事件时,将按钮的可触性设置为false,用delayTime延迟1秒后再设置为true
            var that = this
            var __func = function(_sender,_type){
                switch(_type){
                    case ccui.Widget.TOUCH_ENDED:
                        that.setTouchEnabled(false)
                        _func(_sender,_type)
                        that.runAction(cc.sequence(cc.delayTime(__time),cc.callFunc(function(){
                            that.setTouchEnabled(true)
                        }.bind(that))))

                        break
                }
            }
            this.addTouchEventListener(__func)
            break

        case ccui.Widget.TOUCH_TYPE_DELAY_FRONT:
            //在onEnter事件中,将按钮的可触性设置为false,然后delayTime延迟1秒后再设置为true
            this.setOnEnterCallback(function(){
                this.setTouchEnabled(false)
                this.runAction(cc.sequence(cc.delayTime(__time),cc.callFunc(function(){
                    this.setTouchEnabled(true)
                }.bind(this))))
            }.bind(this))

            if (_func == null){
                return
            }

            var __func = function(_sender,_type){
                switch(_type){
                    case ccui.Widget.TOUCH_ENDED:
                        _func(_sender,_type)
                        break
                }
            }

            this.addTouchEventListener(__func)
            break

        case ccui.Widget.TOUCH_TYPE_ONCE:
            //当触发点击事件时,将按钮的可触性设置为false,在onExit事件中设置为true
            var that = this
            var __func = function(_sender,_type){
                switch(_type){
                    case ccui.Widget.TOUCH_ENDED:
                        that.setTouchEnabled(false)
                        _func(_sender,_type)
                        that.setOnExitCallback(function(){
                            that.setTouchEnabled(true)
                        }.bind(that))
                        break
                }
            }
            this.addTouchEventListener(__func)
            break

        case ccui.Widget.TOUCH_TYPE_ALL_BAN:
            //当触发点击事件时,在最上层添加一层遮罩,吞噬掉所有触摸,在onExit事件中移除遮罩
            var that = this
            var __func = function(_sender,_type){
                switch(_type){
                    case ccui.Widget.TOUCH_ENDED:
                        gAddMask()
                        _func(_sender,_type)
                        that.setOnExitCallback(function(){
                            gRemoveMask()
                        }.bind(that))
                        break
                }
            }
            this.addTouchEventListener(__func)
            break

        case ccui.Widget.TOUCH_TYPE_ALL_BAN_AND_DELAY_FRONT:
            //组合,DELAY_FRONT和ALL_BAN
            this.setOnEnterCallback(function(){
                this.setTouchEnabled(false)
                this.runAction(cc.sequence(cc.delayTime(__time),cc.callFunc(function(){
                    this.setTouchEnabled(true)
                }.bind(this))))
            }.bind(this))

            var that = this
            var __func = function(_sender,_type){
                switch(_type){
                    case ccui.Widget.TOUCH_ENDED:
                        gAddMask()
                        _func(_sender,_type)
                        that.setOnExitCallback(function(){
                            gRemoveMask()
                        }.bind(that))
                        break
                }
            }
            this.addTouchEventListener(__func)
            break

        default:
            this.addTouchEventListener(_func)
            break
    }

}

遮罩层的实现:

function gAddMask(){
    var __scene = cc.director.getRunningScene()
    var __mask_layer = __scene.getChildByName("MaskLayer")
    if(!__mask_layer){
        __mask_layer = new MaskLayer()
        __scene.addChild(__mask_layer,99999)
        __mask_layer.setName("MaskLayer")
    }else{
        __mask_layer.setSwallowTouches(true)
    }
}

function gRemoveMask(){
    var __scene = cc.director.getRunningScene()
    var __mask_layer = __scene.getChildByName("MaskLayer")
    if(__mask_layer){
        __mask_layer.setSwallowTouches(false)
    }
}

var MaskLayer = cc.Layer.extend({

    ctor:function(){
        this._super()

        cc.log("wade MaskLayer ctor")

        this.listener = cc.EventListener.create({
            event: cc.EventListener.TOUCH_ONE_BY_ONE,
            swallowTouches: true,

            onTouchBegan: function (touch, event) {
                cc.log("wade MaskLayer onTouchBegan")
                return true
            },

            onTouchMoved:function (touch, event){
                cc.log("wade MaskLayer onTouchMoved")
            },

            onTouchEnded:function (touch, event){
                cc.log("wade MaskLayer onTouchEnded")
            },
        })

        cc.eventManager.addListener(this.listener, this);

    },

    setSwallowTouches:function(_bool){
        this.listener.setSwallowTouches(_bool)
    }

})

有了以上方法,当我们想创建一个场景跳转并且入场延时响应的按键时:

this.btn_challenge.addTouch(this.startChallenge.bind(this),ccui.Widget.TOUCH_TYPE_DELAY_FRONT_AND_ALL_BAN)

这时候,当连续多次点击这个挑战按钮时,只会进入战斗一次,而原方法会多次进入战斗,并且在onEnter后1秒之后才会响应触摸。

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

jquery.ui.widget.js

  • 2014年12月05日 11:45
  • 15KB
  • 下载

jquery.ui.widget.js

  • 2016年01月21日 17:31
  • 5KB
  • 下载

cocos2dx 源码分析 之Widget 头文件 (3.11.1)

一直想找时间梳理下,虽然我可能讲的不好,但多写多讲才会进步啊!嗯,厚脸皮的试试。...
  • mixi57
  • mixi57
  • 2016年07月04日 17:40
  • 3036

【Cocos2d-x】源码分析之 2d/ui/Widget

cocostudio源码浅析之widget
  • yhhwatl
  • yhhwatl
  • 2014年05月21日 16:16
  • 3586

cocos2dx --- Widget 加载 CCNode

Widget 有 addChild() 与 addNode() 两个方法研究
  • bys0201
  • bys0201
  • 2014年06月05日 16:25
  • 2240

js之widget日历datepicker

一、日历配置 inline: true, defaultDate: 0,//当前时间 若将0改为+1,则为当前时间后的一天 gotoCurrent: tr...

Cocos2d-x实战 JS卷

  • 2017年11月11日 22:16
  • 85.21MB
  • 下载

Cocos2dx 小技巧 Label的换行(js实现)

项目在做聊天的时候会用到。因为用setContentSize方法太局限,因为 :假如我们做的是一个类似微信的聊天对话框,这种对话框一个特点就是会随着你文字长度的改变而改变。而如果我们在这里讲Label...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:cocos-js,Widget的addTouchEventListener改善
举报原因:
原因补充:

(最多只允许输入30个字)