cc.Class
是一个很常用的 API,用于声明 Cocos Creator 中的类,为了方便区分,我们把使用 cc.Class 声明的类叫做 CCClass。
调用 cc.Class
,传入一个原型对象,在原型对象中以键值对的形式设定所需的类型参数,就能创建出所需要的类。
var Sprite = cc.Class({
name: "sprite"
});
使用 ctor
声明构造函数:
var Sprite = cc.Class({
ctor: function () {
cc.log(this instanceof Sprite); // true
}
});
var Sprite = cc.Class({
// 声明一个名叫 "print" 的实例方法
print: function () { }
});
使用 extends
实现继承:
// 父类
var Shape = cc.Class();
// 子类
var Rect = cc.Class({
extends: Shape
});
继承后,CCClass 会统一自动调用父构造函数,你不需要显式调用。
var Shape = cc.Class({
ctor: function () {
cc.log("Shape"); // 实例化时,父构造函数会自动调用,
}
});
var Rect = cc.Class({
extends: Shape
});
var Square = cc.Class({
extends: Rect,
ctor: function () {
cc.log("Square"); // 再调用子构造函数
}
});
var square = new Square();
当声明的属性具备类型时(如:cc.Node
,cc.Vec2
等),可以在声明处填写他们的构造函数来完成声明,如
properties: {
target: cc.Node,
pos: cc.Vec2,
}
当声明属性的类型继承自 cc.ValueType
时(如:cc.Vec2
,cc.Color
或 cc.Rect
),除了上面的构造函数,还可以直接使用实例作为默认值:
properties: {
pos: new cc.Vec2(10, 20),
color: new cc.Color(255, 255, 255, 128),
}
当声明属性是一个数组时,可以在声明处填写他们的类型或构造函数来完成声明,如
properties: {
any: [], // 不定义具体类型的数组
bools: [cc.Boolean],
strings: [cc.String],
floats: [cc.Float],
ints: [cc.Integer],
values: [cc.Vec2],
nodes: [cc.Node],
frames: [cc.SpriteFrame],
}
获得组件所在的节点很简单,只要在组件方法里访问 this.node
变量:
start: function () {
var node = this.node;
node.x = 100;
}
你会经常需要获得同一个节点上的其它组件,这就要用到 getComponent
这个 API,它会帮你查找你要的组件。
start: function () {
var label = this.getComponent(cc.Label);
var text = this.name + ' started';
// Change the text in Label Component
label.string = text;
}
你也可以为 getComponent
传入一个类名。对用户定义的组件而言,类名就是脚本的文件名,并且区分大小写。例如 "SinRotate.js" 里声明的组件,类名就是 "SinRotate"。
var rotate = this.getComponent("SinRotate");
如果在节点上找不到你要的组件,getComponent
将返回 null,如果你尝试访问 null 的值,将会在运行时抛出 "TypeError" 这个错误。因此如果你不确定组件是否存在,请记得判断一下:
start: function () {
var label = this.getComponent(cc.Label);
if (label) {
label.string = "Hello";
}
else {
cc.error("Something wrong?");
}
}
仅仅能访问节点自己的组件通常是不够的,脚本通常还需要进行多个节点之间的交互。例如,一门自动瞄准玩家的大炮,就需要不断获取玩家的最新位置。Cocos Creator 提供了一些不同的方法来获得其它节点或组件。
最直接的方式就是在 属性检查器 中设置你需要的对象。以节点为例,这只需要在脚本中声明一个 type 为 cc.Node
的属性
cc.Class({
extends: cc.Component,
properties: {
// 声明 player 属性
player: {
default: null,
type: cc.Node
}
}
有时候,游戏场景中会有很多个相同类型的对象,像是炮塔、敌人和特效,它们通常都有一个全局的脚本来统一管理。如果用 属性检查器 来一个一个将它们关联到这个脚本上,那工作就会很繁琐。为了更好地统一管理这些对象,我们可以把它们放到一个统一的父物体下,然后通过父物体来获得所有的子物体:
如果你不想用全局变量,你可以使用 require
来实现脚本的跨文件操作
每个脚本都能用 require
+ 文件名(不含路径) 来获取到对方 exports 的对象
常用组件接口
cc.Component
是所有组件的基类,任何组件都包括如下的常见接口(假设我们在该组件的脚本中,以 this 指代本组件):
this.node
:该组件所属的节点实例this.enabled
:是否每帧执行该组件的update
方法,同时也用来控制渲染组件是否显示update(dt)
:作为组件的成员方法,在组件的enabled
属性为true
时,其中的代码会每帧执行onLoad()
:组件所在节点进行初始化时(节点添加到节点树时)执行start()
:会在该组件第一次update
之前执行,通常用于需要在所有组件的onLoad
初始化完毕后执行的逻辑