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,它没有判断出是不是触摸设备,还在用 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 的底层引擎在触摸屏上使用的时候需要强制开启触摸。
当看到这个消息的时候我觉得 “天亮了!”
我抓紧按照他的步骤修改底层引擎:
首先找到引擎位置:
然后一层一层的找到目标文件:
然后用记事本打开或者 notepad++ 打开,搜索 var capabilities =
,找到后再后面添加一段代码:capabilities["touches"] = true;
然后保存关闭。
最后到 cocos 编辑器中,选择开发者
,重新编译引擎
。
上面这个步骤搞完,重新编译打包,在用 electron 套壳完,就可以了!!!
天塌了!!!我还是失败了,但是有的人就可以了。
第五:只有一个原因了!
你看,通过上面几部分,electron 支持触摸、cocos 引擎开启了强制触摸、甚至 electron 也开启了手机模式让 cocos 使用触摸。还是没有办法。
然后我就在 cocos 项目加载之后,打印了一下触摸的配置:
console.log("触摸======>> ", cc.sys.capabilities.touches, cc.sys.capabilities)
然后效果是:本地浏览器肯定没问题,但是我用 electron 打包成 exe 之后,挑事的时候,打印了两次,第一次 cc.sys.capabilities.touches
的值是 undefined
,第二次才是 true
。
也就是说在最开始的时候,他是 undefined
,也就是说在应用启动的最开始,是没有 cc.sys.capabilities.touches
的,后来才有的。
然后百度!搜!资料少的要死,但是后来才大体知道一件事,就是 cocos 在应用启动的时候,会先判断你能不能使用触摸事件,如果能,才给你开启触摸监听,不然的话,不启动触摸监听,通过打印,最开始 cc.sys.capabilities.touches
的值是 undefined
,不支持触摸,所以他就没有开启监听,后来尽管有了,但是他已经判断完了,觉得你设备已经不支持触摸了,怎么判断的呢,下面代码:
const supportTouch = (document.documentElement.ontouchstart !== undefined || document.ontouchstart !== undefined);
解决需要该他引擎源码,麻烦的一比,但是有一种更佳粗暴的方式,那就是改 cocos 构建发布完的文件包的 index.html 文件,给他加一个ontouchstart
,因为源码判断的是只要 ontouchstart
不是 undefined
就开启触摸监听,所以,我们只要初始化一下就可以了:
<script>
// Cocos 解决触摸屏问题
if (document.documentElement.ontouchstart === undefined) document.documentElement.ontouchstart = null
</script>
改完,通过 electron 打包后,完美实现!
擦,难为了我一天,饭都没吃好。
今天就这样,希望这篇博文可以帮助一些小萌新的 cocos 开发程序猿!
拜了个拜!
标签:一体机,web,Cocos,触摸,cocos,electron,监听,打包 From: https://www.cnblogs.com/wjw1014/p/18349914