# Cocos通过Electron打包web应用后,在触屏一体机设备触摸滑动无效问题解决

Cocos通过Electron打包web应用后,在触屏一体机设备触摸滑动无效问题解决

已经很晚了,刚刚解决这个问题,还是想记录一下,因为刚刚接触 cocos 没多久,这个问题困扰了我很久。

背景

接手了一个答题小游戏,由于涉及敏感信息就不在这里截图了,交接到我手里的是用cocos开发的,之前从来没有接触过,于是也是边学边做,由于整体并不是特别的复杂,因此一切也都比较顺利,直到第一版交付到客户手里设备实测,出现了问题。

客户需要将应用程序放到触屏一体机上面进行宣传使用,就是像银行取号的那种机器,类似于下面这种,它其实就是一个 1920 * 1080 的 window 电脑,只不过可以进行触摸罢了:

在这里插入图片描述

我是使用 cocos 编写的代码,写完之后,把项目构建发布成 Web Desktop 或者是 Web Mobile ,其实他们都是差不多的,官方解释是 Cocos Creator 提供了两种 Web 平台的页面模板,可以通过 发布平台 的下拉菜单选择 Web Mobile 或 Web Desktop,他们的区别主要在于 Web Mobile 会默认将游戏视图撑满整个浏览器窗口,而 Web Desktop 允许在发布时指定一个游戏视图的分辨率,而且之后游戏视图也不会随着浏览器窗口大小变化而变化。

构建完成,将构建完成的文件包放到 Electron 程序里面套上壳,生成 exe 文件,然后客户将 exe 文件放到上面说的触屏一体机上用。

问题出现

点击事件、页面切换啥的,一切都很顺利,直到做到一个排序题,需要拖拽选项进行排序的时候发现,一体机上没反应。但是这个拖拽选项的操作在我电脑上,无论是浏览器、还是浏览器手机模式、还是最终通过 electron 打包成 exe 文件,都是可以操作的,只有一体机上没反应。

定位原因

第一:这时候我的第一反应是触屏的原因,毕竟点击事件触摸事件是两回事,而且我自己电脑再怎么测试,鼠标再怎么点,他也是 click 事件而不是 touch 事件。

但是在我查找资料发现,cocos 提供的 touch 事件,是兼容 click 事件的,也就是说,可以简单的理解,只要用 touch 事件写,如果设备不支持 touch 事件的话,他也会帮我们用 click 事件处理,而且我在开发的过程中也是使用的 touch 事件而不是 click 事件。所以我觉得跟 cocos 开发没关系。

第二:我又在想,是不是因为 electron 打包的原因?

electron 在早期的版本是不支持触摸的,但是一想也不对,我是最近新安装的版本,就算不是最新,也到不了早期的程度,肯定是支持触摸的(electron7开始才支持触摸,现在都20多了),但是我还是不放心,我就在 electron 里面监听了一下,他果然支持!擦!不是这个原因。

第三:我又突然一想,是不是因为 electron 打包后,设备放到一体机上,一体机本质上是window PC,会不会 cocos 没有判断出它是触摸设备,于是还在用 click 事件处理?

因为单纯的点击事件是没有任何问题的,因为我是用的 touch 处理的,测试发现 touch_end 监听到了,只有按下没监听到、移动没监听到。只有抬起的时候监听到了。于是我就在 electron 打包的时候,强行开启触摸模式:

  mainWindow.webContents.debugger.attach('1.3');
  mainWindow.webContents.debugger.sendCommand('Emulation.setTouchEmulationEnabled', {
    enabled: true,
    configuration: 'mobile',
  });
  mainWindow.webContents.debugger.sendCommand('Emulation.setEmitTouchEventsForMouse', { enabled: true });

开启之后打包生成的 exe 就模拟手机效果嘛,鼠标变成了小圆圈,很遗憾,我的还是不行,甚至我自己的电脑也不行了,以前我电脑还可以拖拽,开启强制触摸后,也不行了,只能点击事件,和一体机一模一样了。

失败!当然庆幸的是,我还原出来了一体机的问题。

注意哈。有的人,通过上面的配置,就可以成功了!只是我的不行。

第四:我从网上找资料,说是 cocos 的问题,cocos 的底层引擎在触摸屏上使用的时候需要强制开启触摸。

当看到这个消息的时候,和我的问题太相似了,简直就是我遇到的问题,所以我觉得 “天亮了!”

我抓紧按照他的步骤修改底层引擎:

首先找到cocos引擎位置:

在这里插入图片描述

然后一层一层的找到目标文件 CCSys.js

在这里插入图片描述

然后用记事本打开或者 notepad++ 打开,搜索 var capabilities =,找到后再后面添加一段代码:capabilities["touches"] = true; 然后保存关闭。

在这里插入图片描述

最后到 cocos 编辑器中,选择开发者,重新编译引擎

在这里插入图片描述

上面这个步骤搞完,重新编译打包,在用 electron 套壳完,就可以了!!!

于是乎,天塌了!!!我还是失败了,但是有的人就可以了。我已经开始烦了,人家都可以了,就我不行,玄学嘛!!!

第五:到底因为啥子嘛

你看,通过上面几部分,electron 本身是支持处理触摸事件的、cocos 引擎也使用了 touch 触摸、甚至 electron 也强制开启了手机模式让 cocos 执行触摸操作。还是没有实现触摸拖拽效果。

然后我就在 cocos 项目加载之后,打印了一下触摸的配置:

console.log("触摸======>> ", cc.sys.capabilities.touches, cc.sys.capabilities)

然后效果是:本地浏览器肯定没问题,但是我用 electron 打包成 exe 之后,调试的时候,打印出来的结果是 cc.sys.capabilities.touches 的值为 undefined,我无意中切换了一下页面,再返回首页的时候,他再次执行打印出来的才是 true

也就是说在最开始的时候,cc.sys.capabilities.touches 的值是 undefined,也就是说在应用启动的最开始,是没有 cc.sys.capabilities.touches 的,后来才有的。

然后百度!搜!资料少的要死,但是后来才大体知道一件事,就是 cocos 在应用启动的时候,会先判断你的设备支不支持使用触摸事件,如果支持,才给你开启触摸监听,不然的话,不启动触摸监听,就用点击事件。通过上面测试的打印效果发现,最开始 cc.sys.capabilities.touches 的值是 undefined,不支持触摸,所以它就没有开启触摸监听,后来尽管有了,但是它已经判断完了,觉得你设备已经不支持触摸了,所以也没用重启监听触摸事件,它怎么判断的呢,引擎是通过下面的代码:

const supportTouch = (document.documentElement.ontouchstart !== undefined || document.ontouchstart !== undefined);

它判断了一下 document.documentElement.ontouchstart 或者 document.ontouchstart 的值是不是 undefined,如果都是 undefined 则它认为你设备不支持触摸事件。

所以说解决需要修改它这里的引擎源码,又要找又要改的,麻烦的一比。但是!有一种更加粗暴的方式,那就是改 cocos 构建发布完的文件包的 index.html 文件,在它的头部,给他加一个ontouchstart ,因为源码判断的是只要 ontouchstart 不是 undefined 就能顺利开启触摸监听,所以,我们只要初始化一下就可以了:

<script>
    // Cocos 解决触摸屏问题
    if (document.documentElement.ontouchstart === undefined) document.documentElement.ontouchstart = null
</script>

改完之后,再通过 electron 打包后,苍天呐!完美实现了效果!

擦,难为了我一天,饭都没吃好。

今天就这样,希望这篇博文可以帮助一些小萌新的 cocos 开发程序猿!

拜了个拜!

posted @ 2024-08-08 22:59  叫我+V  阅读(18)  评论(0编辑  收藏  举报