参考:https://docs.cocos.com/creator/manual/zh/scripting/access-node-component.html
配置: MacOS 10.12.6 CocosCreator2.3.3 JavaScript VisualCode
访问同节点下的组件
获取同一节点下的其他组件,我们可使用getComponent,比如我们想获取如下节点的Label:
start: function() { // 获取label节点 // 由于node中也存在着一个getComponent方法,因此下面两个的写法一致 var textLabel = this.getComponent(cc.Label); var textLabel = this.node.getComponent(cc.Label); // 添加判定,检测组件是否获取到,若getComponent获取失败,将返回null if (!textLabel) { cc.error('get component failed'); } else { textLabel.string = '获取文本组件'; } // 获取脚本组件 var script = this.getComponent('debugScript'); console.log(script); },
访问其他节点组件
1. 利用属性检查器设置,即在脚本的properties属性中设置节点,比如我们想在TextLabel中访问MenuNode节点:
我们可以在startBtn下的javaScript脚本下添加内容:
properties: { // 值类型属性使用,比如:Number,Vec2, String, Boolean, Enum, Color等 Number:0, Vec2: [], String: '', Boolean: true, // 引用类型属性相关,需要在拖拽对应的节点或者资源,添加了两种方式,可根据图示对比下区别 // 方式1: menuNode1: cc.Node, // 方式2: menuNode2: { default: null, // 设置属性的默认值,该属性值仅在第一次添加到节点时才会使用 type: cc.Node, // 属性的数据类型 visible: true, // 是否在属性检查器中显示该属性 displayName: 'menuNode2', // 在属性检查器中显示成设定的名字 tooltip: 'this is MenuNode2', // 添加属性说明tip }, },
然后把层级管理器中的menuNode节点拖拽到menuNode1,menuNode2中,我们就可以在脚本中获取了。
start: function() { let menuNode = this.menuNode1 console.log('--> menuNode.name:', menuNode.name); // -->menuNode.name:MenuNode },
2. 利用脚本进行查找,我们依然以TextLabel脚本中想获取menuNode的节点为例:
start: function() { /* --------- 获取父节点后再获取指定子节点 ------------*/ // 获取当前的节点 let currentNode = this.node; // 获取父节点,即Canvas let parentNode = this.node.parent; console.log('--> parentNode name:', parentNode.name); // -->parentNode name:Canvas // 获取指定节点 let menuNode = parentNode.getChildByName('MenuNode'); if (menuNode) { console.log('-->menuNode name:', menuNode.name); // -->menuNode name:MenuNode } /* --------- 使用cc.find 方法 ------------*/ let menuBtn = cc.find('Canvas/MenuNode/quitBtn'); if (menuBtn) { console.log('--> menuBtn name:', menuBtn.name); // --> menuBtn name: quitBtn } },
全局变量访问
假设我们有多个脚本存在,我们需要在A脚本里访问B脚本下的属性,我们可以适当且谨慎的使用全局变量。
建议创建一个脚本文件,并命名为GlobalConfig.js文件,这样有有利于查看并维护。比如:
// ------------------- GlobalConfig.js ------------------- // 创建格式为:window.name = {}; window.G = { quitBtn = null, // 获取quitBtn节点 } // -------------------quitScript.js ------------------- // 脚本组件添加在menuNode下的quitBtn节点下 // 一定要确保全局变量初始化,否则会报错,因此添加到onLoad中 onLoad: function() { // 初始化全局变量指定的属性值 G.quitBtn = this.node; }, // -------------------debugScript.js ------------------- // 脚本组件添加在TextLabel中 start: function() { console.log('--> quitBtn name:',G.quitBtn.name) // quitBtn name },
模块访问
其主要实现借助于module.exports 声明模块,通过require + 文件名(不含路径) 来获取模块相关。
// --------- GlobalConfig.js // GlobalConfig.js 在assets/scripts/config中 module.exports = { quitBtn: null, } // ---------quitScript.js var G = require("GlobalConfig"); cc.Class({ extends: cc.Component, onLoad: function() { // 初始化全局变量指定的属性值 G.quitBtn = this.node; }, }); // ---------debugScript.js var G = require("GlobalConfig"); cc.Class({ extends: cc.Component, start: function() { console.log('--> quitBtn name:',G.quitBtn.name) // quitBtn name }, });
拓展:
在上面的示例程序中,声明变量时,我使用了let 与 var, let类似于var,但是仅在代码块内有效,比如
// let的作用域仅在指定的代码块中 { var a = 10; let b = 11; } console.log('var a:',a); // 10 console.log("let b:",b); // Uncaught ReferenceError: b is not defined
为此,for循环的索引很适合用let来声明,比如:
start: function() { // 使用 var, 循环体外数据依然存在 for(var i = 0; i < 10; i++) { var varCount = i; } console.log('--> var i:',i) // --> var i:10 console.log('--> varCount:',i) // --> varCount:10 // 使用let, 循环体外数值报错 for(let index = 0; index < 10; index++) { let letCount = index; } console.log('--> let index:',index) // Uncaught ReferenceError: index is not defined },
...