前言:
在游戏开发中,我么都是通过代码来控制场景中的节点,下面讲解怎么用代码,创建节点、销毁节点、访问节点、访问组件。
一、创建和销毁节点
1. 创建新节点
除了通过场景编辑器创建节点外,我们也可以在脚本中动态创建节点。通过 new cc.Node() 并将它加入到场景中,可以实现整个创建过程。
1cc.Class({ 2 3 4 5 extends: cc.Component, 6 properties: { 7 8 9 10 sprite:{ 11 12 13 //关联编辑器 14 type: cc.SpriteFrame, 15 default: null, 16 } 17 }, 18 start () { 19 20 21 22 var newnode=new cc.Node("Sprite"); //创建一个新的节点 23 var sp=newnode.addComponent(cc.Sprite); //给新节点添加一个<Sprite组件> 24 sp.spriteFrame=this.sprite; // 更改组件的图片 25 newnode.parent=this.node; // 将新节点作为当前节点的子节点 26 this.node.addChild(newnode); // 将新节点作为当前节点的子节点 27 newnode.color=cc.Color.RED; //设置新节点的颜色 28 }, 29});
2. 克隆已有节点
可以通过 cc.instantiate 方法完成.
1cc.Class({ 2 3 4 5 extends: cc.Component, 6 properties: { 7 8 9 10 enemy:{ 11 12 13 // 关联编辑器 14 type: cc.Node, 15 default: null, 16 }, 17 }, 18 start () { 19 20 21 22 var scenes=cc.director.getScene(); // 获得当前场景 23 var node=new cc.instantiate(this.enemy); // 克隆enemy节点 24 node.parent=this.scenes; // 将克隆节点加到场景中 25 node.setPosition(cc.v2(100,100)); //设置节点位置 26 }, 27});
3. 创建预制节点
和克隆已有节点相似,你可以设置一个预制(Prefab)并通过 cc.instantiate 生成节点。
1cc.Class({ 2 3 4 5 extends: cc.Component, 6 properties: { 7 8 9 10 enemy:{ 11 12 13 14 type: cc.Prefab, //类型,预制体 15 default: null, 16 }, 17 }, 18 start: function (){ 19 20 21 22 var scene=cc.director.getScene(); 23 var node=cc.instantiate(this.enemy); // 创建预制体 24 node.parent=scene; 25 node.setPosition(0,0); 26 }, 27});
4. 销毁节点
通过 node.destroy() 函数,可以销毁节点。
注意:
销毁节点并不会立刻被移除,而是在当前帧逻辑更新结束后,统一执行。当一个节点销毁后,该节点就处于无效状态,可以通过 cc.isValid 判断当前节点是否已经被销毁。
1cc.Class({ 2 3 4 5 extends: cc.Component, 6 properties: { 7 8 9 10 target: cc.Node, 11 }, 12 start: function () { 13 14 15 16 // 5 秒后销毁目标节点 17 setTimeout(function () { 18 19 20 21 this.target.destroy(); //销毁节点 22 }.bind(this), 5000); 23 }, 24 update: function (dt) { 25 26 27 28 if (cc.isValid(this.target)) { 29 30 31 //判断是否消除 32 this.target.rotation += dt * 10.0; 33 } 34 }, 35});
5. destroy 和 removeFromParent 的区别
调用一个节点的 removeFromParent 后,它不一定就能完全从内存中释放,因为有可能由于一些逻辑上的问题,导致程序中仍然引用到了这个对象。
因此如果一个节点不再使用了,请直接调用它的 destroy 而不是 removeFromParent 。
destroy 不但会激活组件上的 onDestroy ,还会降低内存泄露的几率,同时减轻内存泄露时的后果。
1node.removeFromParent(); // 将节点从父亲节点移除 2this.node.removeAllChildren(); // 移除所有孩子节点
二、访问节点和组件
1. 访问组件所在的节点
在组件方法里访问 this.node 变量;
var node = this.node;
2. 查找子节点
如果用 属性检查器 来一个一个将它们关联到这个脚本上,那工作就会很繁琐。
为了更好地统一管理这些对象,我们可以把它们放到一个统一的父物体下,然后通过父物体来获得所有的子物体:
1// 查找孩子节点【为一个数组】 2 var cannons = this.node.children; 3 4// getChildByName :出现同名,则返回第一个 5this.node.getChildByName("name"); 6 7//如果子节点的层次较深,你还可以使用 cc.find , cc.find 将根据传入的路径进行逐级查找: 8cc.find("Cannon 01/Barrel/SFX", this.node); 9//全局名字查找,当 cc.find 只传入第一个参数时,将从场景根节点开始逐级查找: 10this.backNode = cc.find("Canvas/Menu/Back");
3. 获得其它组件
获得同一个节点上的其它组 getComponent 这个 API。
1start: function () { 2 3 4 5 var label = this.getComponent(cc.Label);// 获取Label组件 6 7 //获取代码组件:SinRotate.js 里声明的组件,类名就是 SinRotate 8 var rotate = this.getComponent("SinRotate"); 9 10 //在节点上也有一个 getComponent 方法,它们的作用是一样的: 11 cc.log(this.node.getComponent(cc.Label) === this.getComponent(cc.Label)); // true 12 13 //删除组件 14 this.destroy(); 15}
4.利用属性检查器设置节点
首先在代码里面声明属性,然后将目标节点拉拽到属性检查器中!

1cc.Class({ 2 3 4 5 extends: cc.Component, 6 properties: { 7 8 9 10 // 声明 player 属性 11 player: { 12 13 14 15 default: null, 16 type: cc.Node 17 } 18 } 19});
在上面的例子中,如果你将属性的 type 声明为 Player 组件,当你拖动节点 Player Node 到 属性检查器,player 属性就会被设置为 这个节点里面的 Player 组件 。这样你就不需要再自己调用 getComponent 啦
1var Player = require("Player"); 2cc.Class({ 3 4 5 6 extends: cc.Component, 7 properties: { 8 9 10 11 // 声明 player 属性,这次直接是组件类型 12 player: { 13 14 15 16 default: null, 17 type: Player 18 } 19 }, 20 21 start: function () { 22 23 24 25 var playerComp = this.player; 26 this.checkPlayer(playerComp); 27 }, 28});
推荐阅读:
CocosCreator 代码组件(创建与使用、cc.Class类型、生命周期函数)(第三篇)
CocosCreator 触摸事件、鼠标事件、键盘事件、重力传感事件、自定义事件 (第五篇)
本文同步分享在 博客“战 胜”(CSDN)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。