2dx关于js响应layer触摸消息的bug
cocos2dx关于js响应layer触摸消息的bug
cocos2d-x 3.7
问题描述:
目前这个版本中(3.7),c++层的layer触摸消息只能通过消息的方式发送给js,不能像lua一样直接回调js注册的触摸回调接口,为了方便,我们更改一下layer类的onTouchBegan/onTouchMove...
等接口,使其支持在layer的触摸响应中直接回调js接口。
具体实现见:http://www.cnblogs.com/songcf/p/4764444.html
ok,在这之后就会发现ScriptingCore中有一个触摸响应判断的bug:
只要c++对js的ontouchbegan函数调用成功,都会被视为当前layer捕捉到了该触摸(即return true)
如果该layer开启了吞噬触摸,那么此次touch永远被该layer捕获,不再传递下去,即使你在js层中注册的onTouchBegan是return false,也无济于事。
那么造成该bug的原因如下:
//Layer判断是否捕获该touch,取决于executeScriptTouchHandler函数调用的返回值
bool Layer::onTouchBegan(Touch *touch, Event *event)
{
#if CC_ENABLE_SCRIPT_BINDING
if (kScriptTypeNone != _scriptType)
{
return executeScriptTouchHandler(EventTouch::EventCode::BEGAN, touch, event) == 0 ? false : true;
}
#endif
CC_UNUSED_PARAM(event);
CCASSERT(false, "Layer#ccTouchBegan override me");
return true;
}
//再来看看executeScriptTouchHandler的返回值,取决于ScriptingCore::sendEvent
int Layer::executeScriptTouchHandler(EventTouch::EventCode eventType, Touch* touch, Event* event)
{
#if CC_ENABLE_SCRIPT_BINDING
if (kScriptTypeNone != _scriptType)
{
TouchScriptData data(eventType, this, touch, event);
ScriptEvent scriptEvent(kTouchEvent, &data);
return ScriptEngineManager::getInstance()->getScriptEngine()->sendEvent(&scriptEvent);
}
#endif
//can not reach it
return 0;
}
//再看sendEvent中发送触摸消息的代码
//这里可以看出layer是否捕获触摸取决于handleTouchEvent的返回值
int ScriptingCore::sendEvent(ScriptEvent* evt)
{
//......
case kTouchEvent:
{
TouchScriptData* data = (TouchScriptData*)evt->data;
return handleTouchEvent(data->nativeObject, data->actionType, data->touch, data->event);
}
break;
case kTouchesEvent:
{
TouchesScriptData* data = (TouchesScriptData*)evt->data;
return handleTouchesEvent(data->nativeObject, data->actionType, data->touches, data->event);
}
break;
//......
}
//你可以继续往下跟进去就会知道,最终返回的值到底是什么
没错!如你所见,最后的返回值是JS_CallFunctionName是否调用成功,即这里c++调用js的onTouchBegan函数是否成功
只要调用成功,touch就会被该layer捕获!跟onTouchBegan的返回值没半毛钱关系。那么正确的返回值应该是js端onTouchBegan的返回值。
解决方案:
修改ScriptingCore
中handleTouchEvent/handleTouchesEvent
两个接口,让它们的返回值为js端onTouchBegan的返回值:
bool ScriptingCore::handleTouchEvent(void* nativeObj, cocos2d::EventTouch::EventCode eventCode, cocos2d::Touch* touch, cocos2d::Event* event)
{
JS::RootedValue ret(_cx);
if (handleTouchEvent(nativeObj, eventCode, touch, event, &ret)){
return JS::ToBoolean(ret);
}
else {
return false;
}
}
bool ScriptingCore::handleTouchesEvent(void* nativeObj, cocos2d::EventTouch::EventCode eventCode, const std::vector<cocos2d::Touch*>& touches, cocos2d::Event* event)
{
JS::RootedValue ret(_cx);
if (handleTouchesEvent(nativeObj, eventCode, touches, event, &ret)){
return JS::ToBoolean(ret);
}
else {
return false;
}
}
其实我不太明白官方为什么在layer的触摸响应中,只用c++回调lua接口,而js使用发消息的方式(不用c++回调js接口),性能?!
2dx关于js响应layer触摸消息的bug的更多相关文章
- Glide.js:响应式 & 触摸友好的 jQuery 滑块插件
Glide.js 是一款响应式和对触摸友好的 jQuery 滑块.基于 CSS3 转换实现,并在低版本浏览器降级处理.Glide.js 简单,重量轻,快速,适用于智能手机,平板电脑和台式机.它支持 s ...
- jQuery响应式幻灯片插件jquery.glide.js(支持触摸&轻量级)
找到一款好的幻灯片插件不容易,找到一款功能全并且使用很简单的幻灯片更不容易,今天为大家分享一款全能的幻灯片插件glide.js,也是我现在在使用的一款插件. jquery.glide.js是响应和触摸 ...
- 关于js-binding中Layer触摸事件的优化
关于js-binding中Layer触摸事件的优化 cocos2d-x 3.7 1. 目前js中监听触摸事件带来的不便(特别是cocosbuilder) 在目前的js-binding中,如果要监听la ...
- ImageLightbox.js – 响应式的图片 Lightbox 插件
ImageLightbox.js 是一款很简洁的用于显示图片灯箱效果(Lightbox)的插件,没有字幕,导航按钮或默认背景.如果默认功能不够用的话,你可以很容易地自定义 JavaScript 函数扩 ...
- layer.js中layer.tips
<script src="~/Content/js/layer/layer.js"></script> layer.tips('名称不能为空', '#pro ...
- Chocolat.js – 响应式的 jQuery Lightbox 插件
Chocolat.js 使您能够显示一个或多个图像在同一页面上.给用户展示一组图片缩略图,可以显示全页或块.Chocolat.js 可以很好地处理所有主要的浏览器.它在下面这些浏览器测试通过:IE7+ ...
- Dense.js - 响应式的视网膜(Rtina)图像支持
Dense 是一款 jQuery 插件,它提供一个简单的方法为设备提供精密像素比的图像,为你的网站带来视网膜支持,清除模糊,图像更清晰.通过简单地包括 jQuery 插件的页面上,就能实现响应式的视网 ...
- duilib进阶教程 -- 响应windows原生消息和自定义消息(13)
一.windows原生消息 同样,入门教程只是给出了响应windows原生消息的方法,并没给出例子,这里以自适应屏幕分辨率为例.迅雷播放器虽然可以在启动的时候自动调整窗口大小,但是当屏幕分辨率实时改变 ...
- vue.js响应式原理解析与实现
vue.js响应式原理解析与实现 从很久之前就已经接触过了angularjs了,当时就已经了解到,angularjs是通过脏检查来实现数据监测以及页面更新渲染.之后,再接触了vue.js,当时也一度很 ...
随机推荐
- 网易及新浪IP查询接口
通过IP地址获取对应的地区信息通常有两种方法:1)自己写程序,解析IP对应的地区信息,需要数据库.2)根据第三方提供的API查询获取地区信息. 第一种方法,参见文本<通过纯真IP数据库获取IP地 ...
- 用python实现远程复制 (scp + expect )
scp 功能很强大,但需要人工输入 password, 当然可以通过把 公钥保存在远程主机的 ~/.ssh 目录中,而后就不用输入password,但这需要配置. 用 sshpass 可能在命令输入 ...
- I/O小总结
//判断不存在就创建目录 ,然后拷贝文件 DirectoryInfo di = null; if (!Directory.Exists(n.Attribute("value").V ...
- iOS开发-用预处理指令代替注释
有时候我们在调试程序的时候,想不执行某一段代码或者某些方法,我们会用注释,但是这样看上去就会让你的代码显示“很绿”,此时我们可以用一下代码 #if 0 // 你不想执行的代码 #endif 这样就可以 ...
- 安装Exchange2010
1.exadmin加入到 Schema admins,enterprise admins组中 CAS,HUB,MB安装.Net Framework CAS,HUB:2.Run 'ServerManag ...
- SQL Server-删除表中重复的记录!
比如现在有一人员表 (表名:peosons)若想将姓名.身份证号.住址这三个字段完全相同的记录查询出来 select p1.* from persons p1,persons p ...
- Codeforces Gym 100531I Instruction 构造
Problem I. Instruction 题目连接: http://codeforces.com/gym/100531/attachments Description Ingrid is a he ...
- codeforces 377A. Puzzles 水题
A. Puzzles Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/problemset/problem/33 ...
- hdu 5276 YJC tricks time 数学
YJC tricks time Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?p ...
- 微信公共服务平台开发(.Net 的实现)11-------客服消息(定项消息推送 重要的OPENID)
这次我们来一起研究一下“客服消息”,首先明确一下“客服消息”的概念.这不同于之前的“被动响应消息”,也就是说并不是之前“你一言我一语的即时响应”,可能在某种情况下你需要给不同的人主动发送消息,例如你的 ...