访问节点和组件

属性检查器 里修改节点和组件,也能在脚本中动态修改。动态修改的好处是能够在一段时间内连续地修改属性、过渡属性,实现渐变效果。脚本还能够响应玩家输入,能够修改、创建和销毁节点或组件,实现各种各样的游戏逻辑。要实现这些效果,你需要先在脚本中获得你要修改的节点或组件。 在本篇教程,我们将介绍如何

  • 属性检查器 设置节点和组件
  • -

    获得组件所在的节点

    this.node 变量:
    1. start: function () { var node = this.node; node.x = 100; }

    获得其它组件

    getComponent 这个 API,它会帮你查找你要的组件。
    1. start: function () { var label = this.getComponent(cc.Label); var text = this.name + ' started'; // Change the text in Label Component label.string = text; }
    getComponent 传入一个类名。
    1. var label = this.getComponent("cc.Label");
    区分大小写。例如 “SinRotate.js” 里声明的组件,类名就是 “SinRotate”。
    1. var rotate = this.getComponent("SinRotate");
    getComponent 方法,它们的作用是一样的:
    1. start: function () { cc.log( this.node.getComponent(cc.Label) === this.getComponent(cc.Label) ); // true }
    getComponent 将返回 null,如果你尝试访问 null 的值,将会在运行时抛出 “TypeError” 这个错误。因此如果你不确定组件是否存在,请记得判断一下:
    1. start: function () { var label = this.getComponent(cc.Label); if (label) { label.string = "Hello"; } else { cc.error("Something wrong?"); } }

    获得其它节点及其组件

    仅仅能访问节点自己的组件通常是不够的,脚本通常还需要进行多个节点之间的交互。例如,一门自动瞄准玩家的大炮,就需要不断获取玩家的最新位置。Cocos Creator 提供了一些不同的方法来获得其它节点或组件。

    利用属性检查器设置节点

    属性检查器 中设置你需要的对象。以节点为例,这只需要在脚本中声明一个 type 为 cc.Node 的属性:
    1. // Cannon.jscc.Class({ extends: cc.Component, properties: { // 声明 player 属性 player: { default: null, type: cc.Node } }});
    properties 里面声明了一个 player 属性,默认值为 null,并且指定它的对象类型为 cc.Node。这就相当于在其它语言里声明了 public cc.Node player = null;。脚本编译之后,这个组件在 属性检查器 中看起来是这样的: 接着你就可以将层级管理器上的任意一个节点拖到这个 Player 控件: 这样一来它的 player 属性就会被设置成功,你可以直接在脚本里访问 player:
    1. // Cannon.jsvar Player = require("Player");cc.Class({ extends: cc.Component, properties: { // 声明 player 属性 player: { default: null, type: cc.Node } }, start: function () { var playerComp = this.player.getComponent(Player); this.checkPlayer(playerComp); }, // ...});

    利用属性检查器设置组件

    属性检查器,player 属性就会被设置为这个节点里面的 Player 组件。这样你就不需要再自己调用 getComponent 啦。
    1. // Cannon.jsvar Player = require("Player");cc.Class({ extends: cc.Component, properties: { // 声明 player 属性,这次直接是组件类型 player: { default: null, type: Player } }, start: function () { var playerComp = this.player; this.checkPlayer(playerComp); }, // ...});
    null 改为数组[],这样你就能在 属性检查器 中同时设置多个对象。

不过如果需要在运行时动态获取其它对象,还需要用到下面介绍的查找方法。

查找子节点

属性检查器 来一个一个将它们关联到这个脚本上,那工作就会很繁琐。为了更好地统一管理这些对象,我们可以把它们放到一个统一的父物体下,然后通过父物体来获得所有的子物体:

  1. // CannonManager.jscc.Class({ extends: cc.Component, start: function () { var cannons = this.node.children; // ... }});

getChildByName

  1. this.node.getChildByName("Cannon 01");

cc.findcc.find 将根据传入的路径进行逐级查找:

  1. cc.find("Cannon 01/Barrel/SFX", this.node);

全局名字查找

cc.find 只传入第一个参数时,将从场景根节点开始逐级查找:

  1. this.backNode = cc.find("Canvas/Menu/Back");

访问已有变量里的值

如果你已经在一个地方保存了节点或组件的引用,你也可以直接访问它们,一般有两种方式:

你应当很谨慎地使用全局变量,当你要用全局变量时,应该很清楚自己在做什么,我们并不推荐滥用全局变量,即使要用也最好保证全局变量只读。 window.Global,这个对象里面包含了 backNodebackLabel 两个属性。

  1. // Globals.js, this file can have any namewindow.Global = { backNode: null, backLabel: null,};

window. 不可省略。

接着你可以在合适的地方直接访问并初始化 Global:

  1. // Back.jscc.Class({ extends: cc.Component, onLoad: function () { Global.backNode = this.node; Global.backLabel = this.getComponent(cc.Label); }});

Global 里的值:

  1. // AnyScript.jscc.Class({ extends: cc.Component, // start 会在 onLoad 之后执行,所以这时 Global 已经初始化过了 start: function () { var text = 'Back'; Global.backLabel.string = text; }});

添加全局变量时,请小心不要和系统已有的全局变量重名。

你需要小心确保全局变量使用之前都已初始化和赋值。

通过模块访问

require 来实现脚本的跨文件操作,让我们看个示例:

  1. // Global.js, now the filename mattersmodule.exports = { backNode: null, backLabel: null,};

require + 文件名(不含路径) 来获取到对方 exports 的对象。

  1. // Back.js// this feels more safe since you know where the object comes fromvar Global = require("Global");cc.Class({ extends: cc.Component, onLoad: function () { Global.backNode = this.node; Global.backLabel = this.getComponent(cc.Label); }});
  1. // AnyScript.js// this feels more safe since you know where the object comes fromvar Global = require("Global");cc.Class({ extends: cc.Component, // start 会在 onLoad 之后执行,所以这时 Global 已经初始化过了 start: function () { var text = "Back"; Global.backLabel.string = text; }});

模块化。

常用节点和组件接口。