CocosCreator之控制游戏触点数量

摘要

在一部分游戏开发中,多点触控并不是被期望的。官方在 v2.3.0 版本时提供了单点触控的开关,但是并不能指定触点数量,且旧版本没法使用,那么可不可以实现这一功能呢?

正文

测试版本

CocosCreator 版本 2.0.5
CocosCreator 版本 2.1.2
CocosCreator 版本 2.3.4
CocosCreator 版本 2.4.2

思维过程

控制开关 cc.macro.ENABLE_MULTI_TOUCH 是新版才有的,想兼容旧版本还是要去更根源的地方找,跑到源码里先看看触摸事件最开始在哪里分发的!首先想到的是,既然在浏览器端可以进行点击,必然会走注册事件的方法,去源码里搜一下 window.addEventListener,看了一下,果然有个翻译过来像输入的脚本 CCInputManager.js。然后在这个脚本中搜一下 touchstart 果然找到了对应的方法:

/**
 * @method handleTouchesBegin
 * @param {Array} touches
 */
handleTouchesBegin (touches) {
    let selTouch, index, curTouch, touchID,
        handleTouches = [], locTouchIntDict = this._touchesIntegerDict,
        now = sys.now();

    for (let i = 0, len = touches.length; i < len; i ++) {
        selTouch = touches[i];
        touchID = selTouch.getID();
        index = locTouchIntDict[touchID];

        if (index == null) {
            let unusedIndex = this._getUnUsedIndex();
            if (unusedIndex === -1) {
                cc.logID(2300, unusedIndex);
                continue;
            }

            //curTouch = this._touches[unusedIndex] = selTouch;
            curTouch = this._touches[unusedIndex] = new cc.Touch(selTouch._point.x, selTouch._point.y, selTouch.getID());
            curTouch._lastModified = now;
            curTouch._setPrevPoint(selTouch._prevPoint);
            locTouchIntDict[touchID] = unusedIndex;
            handleTouches.push(curTouch);
        }
    }

    if (handleTouches.length > 0) {
        this._glView._convertTouchesWithScale(handleTouches);
        let touchEvent = new cc.Event.EventTouch(handleTouches);
        touchEvent._eventCode = cc.Event.EventTouch.BEGAN;
        eventManager.dispatchEvent(touchEvent);
    }
}

代码的逻辑是处理传入的多个触点,为每个触点分配一个未使用的 id,排好序后分发出去,我们想控制触点的数量,那么是不是可以从获取 未分配的 id 入手呢,我最多允许分配固定数量的 ID 是不是就可以控制最大触点数量?看下分配的方法:

_getUnUsedIndex () {
    let temp = this._indexBitsUsed;
    let now = cc.sys.now();
    for (let i = 0; i < this._maxTouches; i++) {
        if (!(temp & 0x00000001)) {
            this._indexBitsUsed |= (1 << i);
            return i;
        }
        else {
            let touch = this._touches[i];
            if (now - touch._lastModified > TOUCH_TIMEOUT) {
                this._removeUsedIndexBit(i);
                delete this._touchesIntegerDict[touch.getID()];
                return i;
            }
        }
        temp >>= 1;
    }
    // all bits are used
    return -1;
}

分配时有个 this._touches 数组存储这些触点,经过一次 For 循环分配 ID,最多分配 this._maxTouches 个 ID。这样就明白了,干脆改掉 _maxTouches 就能限制分配的数量了,先改成一,然后拿手机扫码试试。成了!再搞成 0 试试,果然触摸失效了!!!完美!

更好的实现

魔改下引擎后,换项目或者引擎版本无法做到复用,有没有更好的办法呢?当然,插件脚本就能实现这个需求,在 CocosCreator 中脚本执行顺序为:Cocos2d 引擎最先执行,然后是插件脚本(有多个的话按项目中的路径字母顺序依次加载),最后才是我们写的普通脚本(打包后只有一个文件,内部按 require 的依赖顺序依次初始化)。

那就将这个修改写进 k-cocos.js 扩展脚本中,声明一个方法挂载到 cc 上吧,CCInputManager.js 脚本最末尾有着导出的逻辑:

module.exports = cc.internal.inputManager = inputManager;

不同的版本还不一样,新版是 cc.internal,比较旧的版本是 _cc.inputManager,那就只好做下兼容处理。

// 触点数量控制
cc.kMultTouch = function (count) {
    // 2.3.0 版本以上
    if (cc.internal && cc.internal.inputManager) {
        cc.internal.inputManager._maxTouches = count;
        return;
    }
    // 低版本
    if (_cc && _cc.inputManager) {
        _cc.inputManager._maxTouches = count;
    }
    // 低版本兼容 QQ_PLAY 的一段逻辑
    if (CC_QQPLAY && BK && BK.inputManager) {
        BK.inputManager._maxTouches = count;
    }
}

结语

扩展脚本已经开源,实现了游戏速率控制、全局触点数量控制、也扩展了节点的一些属性和方法,还有许多想法没加进去,欢迎大家提建议、给点个星星 Star,欢迎加入讨论 QQ 群:1085201157

GitHub地址: https://github.com/KuoKuo666/k-cocos

个人网站:www.kuokuo666.com

2020!我们一起进步!O(∩_∩)O~~

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

KUOKUO众享

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值