热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

cocoscreator事件普通节点注册click事件

在做一个消除类游戏时,需要对点击的方块做出响应。代码很简单,可背后的原理还多着呢。普通节点注册click事件在cc中如果需要相应click事件&#x

在做一个消除类游戏时,需要对点击的方块做出响应。代码很简单,可背后的原理还多着呢。


  1. 普通节点注册click事件

在cc中如果需要相应click事件,需要为该节点添加一个Button组件。或使用类似效果的事件比如

cc.Node.EventType.MOUSE_DOWN

cc.Node.EventType.TOUCH_END

//author herbert qq:464884492
//注册按钮click事件
btn.node.on(“click”, event=>{cc.log(“button click”)});
//注册MOUSE_DOWN
btn.node.on(cc.Node.EventType.MOUSE_DOWN,event=>{cc.log(“button MOUSE_DOWN”)});
//注册TOUCH_END
btn.node.on(cc.Node.EventType.TOUCH_END,event=>{cc.log(“button TOUCH_END”)})


  1. 应该减少事件注册量

是否没有问题了?在写juqery时,有事件委托(delegate)的概念。啥意思呢,就是在节点的父级注册事件,来响应子节点的事件源。为啥可以实现,主要归功于js事件的两大机制

事件冒泡,事件响应从子节点往上冒泡到顶层节点

事件捕获,事件响应冲顶层节点依次传递到最末级节点

所以问题来了,消除类游戏都是通过预制资源生成不同样式的方块。若在每一方块上都注册事件,势必导致内存上涨(虽然现在内存很大了)。看看cc文档,事件机制完全是一样的(最终都是JS),然而我想在我的Canvas上注册一个click事件,问题出现了。

3.问题来了

问题就是我在Canvas上注册了click事件,点击button时,Canvas 上居然没有收到我的click事件。由此我查看cc源码,写了一堆测试代码,最总得出以下结

click事件确实Button组件特殊存

click事件不会向上或向下传递

node.emit触发事件不会向上或向下传递

node.dispatchEvent支持事件向上或向下传递

使用node.dispatchEvent参数必须是 cc.Event.EventCustom对象

4.click事件特殊在哪里

cc.Button 组件中的click事件,其实是cc的自定义事件,源码为证

//author:herbert wx:464884492

this.node.on(cc.Node.EventType.TOUCH_END, this._onTouchEnded, this);

_onTouchEnded (event) {
if (!this.interactable || !this.enabledInHierarchy) return;
if (this._pressed) {
cc.Component.EventHandler.emitEvents(this.clickEvents, event);
this.node.emit(‘click’, this);//触发事件
}
this._pressed = false;
this._updateState();
event.stopPropagation(); //停止冒泡
},

所以,之所Button能响应click事件,是因为组件注册了TOUCH_END事件,并在响应该事件函数中发射一个click事件。


  1. Javascript 自定义事件

参考mdn文档,js自定事件方式如下

// author:herbert wx:464884492
5.了解下cc.node.emit

cc.node.emit 最终调用的是CallbacksInvoker.prototype.invoke 方法,从源码来看,是从对应的缓存对象中找到注册的回调方法,依次调用回调函数。

//author herbert wx:464884492
CallbacksInvoker.prototype.invoke = function (key, p1, p2, p3, p4, p5) {
var list = this._callbackTable[key];
if (list) {
var rootInvoker = !list.isInvoking;
list.isInvoking = true;
var callbacks = list.callbacks;
var targets = list.targets;
for (var i = 0, len = callbacks.length; i var callbmhtack = callbacks[i];
if (callback) {
var target = targets[i];
if (target) {
callback.call(target, p1, p2, p3, p4, p5);
}
else {
callback(p1, p2, p3, p4, p5);
}
}
}
if (rootInvoker) {
list.isInvoking = false;
if (list.containCanceled) {
list.purgeCanceled();
}
}}};

所以click自然不会往上或往下传递。

6.dispatchEvent,事件冒泡

dispatchEvent 利用自定义事件的 bubbles 属性,实现冒泡。至于为啥使用 btn.node.dispatchEvent(new cc.Event.EventMouse(cc.Node.EventType.MOUSE_DOWN, true))没有触发事件是因为cc在底层,将事件类型统一改成了 cc.Event.MOUSE,源码为证

author:herbert wx:464884492

var EventMouse = function (eventType, bubbles) {
cc.Event.call(this, cc.Event.MOUSE, bubbles);

};


推荐阅读
  • 本文探讨了如何利用RxJS库在AngularJS应用中实现对用户单击和拖动操作的精确区分,特别是在调整区域大小的场景下。 ... [详细]
  • 本文探讨了如何通过优化 DOM 操作来提升 JavaScript 的性能,包括使用 `createElement` 函数、动画元素、理解重绘事件及处理鼠标滚动事件等关键主题。 ... [详细]
  • publicclassBindActionextendsActionSupport{privateStringproString;privateStringcitString; ... [详细]
  • 本文探讨了在UIScrollView上嵌入Webview时遇到的一个常见问题:点击图片放大并返回后,Webview无法立即滑动。我们将分析问题原因,并提供有效的解决方案。 ... [详细]
  • 本文介绍了如何使用 Gesture Detector 和 overridePendingTransition 方法来实现滑动界面和过渡动画。 ... [详细]
  • JavaScript 跨域解决方案详解
    本文详细介绍了JavaScript在不同域之间进行数据传输或通信的技术,包括使用JSONP、修改document.domain、利用window.name以及HTML5的postMessage方法等跨域解决方案。 ... [详细]
  • ASP.NET 进度条实现详解
    本文介绍了如何在ASP.NET中使用HTML和JavaScript创建一个动态更新的进度条,并通过Default.aspx页面进行展示。 ... [详细]
  • 本文探讨了如何在PHP与MySQL环境中实现高效的分页查询,包括基本的分页实现、性能优化技巧以及高级的分页策略。 ... [详细]
  • H5技术实现经典游戏《贪吃蛇》
    本文将分享一个使用HTML5技术实现的经典小游戏——《贪吃蛇》。通过H5技术,我们将探讨如何构建这款游戏的两种主要玩法:积分闯关和无尽模式。 ... [详细]
  • 利用Node.js实现PSD文件的高效切图
    本文介绍了如何通过Node.js及其psd2json模块,快速实现PSD文件的自动化切图过程,以适应项目中频繁的界面更新需求。此方法不仅提高了工作效率,还简化了从设计稿到实际应用的转换流程。 ... [详细]
  • 长期从事ABAP开发工作的专业人士,在面对行业新趋势时,往往需要重新审视自己的发展方向。本文探讨了几位资深专家对ABAP未来走向的看法,以及开发者应如何调整技能以适应新的技术环境。 ... [详细]
  • 本文详细介绍了 `org.apache.tinkerpop.gremlin.structure.VertexProperty` 类中的 `key()` 方法,并提供了多个实际应用的代码示例。通过这些示例,读者可以更好地理解该方法在图数据库操作中的具体用途。 ... [详细]
  • Beetl是一款先进的Java模板引擎,以其丰富的功能、直观的语法、卓越的性能和易于维护的特点著称。它不仅适用于高响应需求的大型网站,也适合功能复杂的CMS管理系统,提供了一种全新的模板开发体验。 ... [详细]
  • 本文探讨了如何在游戏启动画面中移除广告,特别是在游戏数据加载期间(大约5-6秒)广告会短暂显示的问题。通过调整XML布局和代码逻辑,可以实现广告的延迟加载或完全移除。 ... [详细]
  • SwipeRefreshLayout 是一个常用的刷新控件,可以包裹一个可滑动的子控件(如 ListView 或 RecyclerView)以实现竖直滑动时的页面刷新。然而,它本身并不支持上拉加载更多。本文将介绍如何通过继承 SwipeRefreshLayout 来实现这一功能。 ... [详细]
author-avatar
哈罗xeh_406
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有