• cocos2dx-js——Widget的addTouchEventListener改善


    本文转载于:http://blog.csdn.net/wade333777/article/details/51537357

    一、基本使用


    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秒之后才会响应触摸。

  • 相关阅读:
    6-8 adaboost分类器2
    6-7 adaboost分类器1
    6-6 Haar特征3
    6-5 Haar特征2
    6-4 Haar特征1
    6-3 图片合成视频
    6-2 视频分解图片
    Linux操作系统六大优点
    Linux系统正则表达式用法笔记
    Linux系统正则表达式用法笔记
  • 原文地址:https://www.cnblogs.com/guangyun/p/8391553.html
Copyright © 2020-2023  润新知