一、类的构造
-
cc.Class == 类型声明
var Sprite = cc.Class({ name: "sprite" });
-
实例化,
var obj = new Sprite();
-
判断实例,
obj instanceof Sprite
-
判断两个类的继承关系,
cc.isChildClassOf(child, parent)
-
构造函数,
var Sprite = cc.Class({ ctor: function () { cc.log(this instanceof Sprite); // true } });
-
继承,
// 父类 var Shape = cc.Class(); // 子类 var Rect = cc.Class({ extends: Shape });
-
静态变量和静态方法
var Sprite = cc.Class({ statics: { // 声明静态变量 count: 0, // 声明静态方法 getBounds: function (spriteList) { // ... } } });
-
设置组件执行优先级
cc.Class({ extends: cc.Component, editor: { executionOrder: -1 }, onLoad: function () { cc.log('Player onLoad!'); } });
executionOrder
越小,该组件相对其它组件就会越先执行。 executionOrder
默认为 0,因此设置为负数的话,就会在其它默认的组件之前执行。
二、声明属性
通过在组件脚本中声明属性,我们可以将脚本组件中的字段可视化地展示在 属性检查器 中,从而方便地在场景中调整属性值。
要声明属性,仅需要在 cc.Class 定义的 properties 字段中,填写属性名字和属性参数即可。
1. 简单声明
-
当声明的属性为基本 JavaScript 类型时,可以直接赋予默认值:
properties: { height: 20, // number type: "actor", // string loaded: false, // boolean target: null, // object }
-
当声明的属性具备类型时(如: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], }
2.完整声明
有些情况下,我们需要为属性声明添加参数,这些参数控制了属性在 属性检查器 中的显示方式,以及属性在场景序列化过程中的行为。
properties: {
score: {
default: 0,
displayName: "Score (player)",
tooltip: "The score of player",
},
scoreDisplay: {
default: null,
type: cc.Label
}
}
下面是常用参数:
-
default: 设置属性的默认值,这个默认值仅在组件第一次添加到节点上时才会用到.
-
type: 限定属性的数据类型
-
visible: 设为 false 则不在 属性检查器 面板中显示该属性。默认情况下,是否显示在 属性检查器 取决于属性名是否以下划线 _ 开头。如果以下划线开头,则默认不显示在 属性检查器,否则默认显示。
properties: { _id: { // 下划线开头原本会隐藏 default: 0, } }
-
serializable: 设为 false 则不序列化(保存)该属性
-
displayName: 在 属性检查器 面板中显示成指定名字
-
tooltip: 当鼠标移到参数上时,显示对应的 Tooltip
-
override:所有属性都将被子类继承,如果子类要覆盖父类同名属性,需要显式设置 override 参数,否则会有重名警告
-
readonly:在 属性检视器 面板中只读
-
min:限定数值在编辑器中输入的最小值
-
max:限定数值在编辑器中输入的最大值
-
step:指定数值在编辑器中调节的步长
-
slide:在 属性检视器 面板中显示为滑动条
数组声明:
数组的 default 必须设置为 [],如果要在 属性检查器 中编辑,还需要设置 type 为构造函数,枚举,或者 cc.Integer,cc.Float,cc.Boolean 和 cc.String。
properties: {
names: {
default: [],
type: [cc.String] // 用 type 指定数组的每个元素都是字符串类型
},
enemies: {
default: [],
type: [cc.Node] // type 同样写成数组,提高代码可读性
},
}
3.get/set 声明
在属性中设置了 get 或 set 以后,访问属性的时候,就能触发预定义的 get 或 set 方法。
properties: {
width: {
get: function () {
return this._width;
},
set: function (value) {
this._width = value;
}
}
}
三、生命周期回调
目前提供给用户的生命周期回调函数主要有:
- onLoad === 做一些初始化相关的操作
- start === 第一次执行 update 之前触发,通常用于初始化一些中间状态的数据,这些数据可能在 update 时会发生改变,并且被频繁的 enable 和 disable。
- update === 每一帧渲染前更新物体的行为,状态和方位
- lateUpdate === 每一帧渲染后执行
- onDestroy === 当组件或者所在节点调用了 destroy(),则会调用 onDestroy 回调,并在当帧结束时统一回收组件。
- onEnable === 当组件的 enabled 属性从 false 变为 true 时,或者所在节点的 active 属性从 false 变为 true 时,会激活 onEnable 回调
- onDisable === 当组件的 enabled 属性从 true 变为 false 时,或者所在节点的 active 属性从 true 变为 false 时,会激活 onDisable 回调
四、访问节点和组件
1. 获得组件所在的节点
只要在组件方法里访问 this.node 变量.
start: function () {
var node = this.node;
node.x = 100;
}
2. 获得其他组件
你会经常需要获得同一个节点上的其它组件,这就要用到 getComponent 这个 API.
start: function () {
var label = this.getComponent(cc.Label);
var text = this.name + ' started';
// Change the text in Label Component
label.string = text;
}
对用户定义的组件而言,类名就是脚本的文件名,并且区分大小写。例如 “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?");
}
}
3. 查找子节点
1️⃣this.node.children;
2️⃣this.node.getChildByName("Cannon 01");
3️⃣cc.find("Cannon 01/Barrel/SFX", this.node);
当 cc.find 只传入第一个参数时,将从场景根节点开始逐级查找:
this.backNode = cc.find("Canvas/Menu/Back");
4. 通过全局变量访问
// Globals.js, this file can have any name
window.Global = {
backNode: null,
backLabel: null,
};
5. 通过模块访问
module.exports = {
backNode: null,
backLabel: null,
};
每个脚本都能用 require + 文件名(不含路径) 来获取到对方 exports 的对象。
五、节点相关操作
1. 激活、关闭节点
this.node.active = false;
2. 更改节点的父节点
this.node.parent = parentNode;
等价于
this.node.removeFromParent(false);
parentNode.addChild(this.node);
3. 索引节点的子节点
this.node.children
将返回节点的所有子节点数组。
this.node.childrenCount
将返回节点的子节点数量。
以上两个 API 都只会返回节点的直接子节点,不会返回子节点的子节点
4. 更改节点的属性(位置、旋转、缩放、尺寸)
-
更改位置
this.node.x = 100; this.node.y = 50; this.node.position = cc.v2(100, 50); this.node.setPosition(100, 50); this.node.setPosition(cc.v2(100, 50));
-
更改旋转
this.node.rotation = 90; this.node.setRotation(90);
-
更改缩放
this.node.scaleX = 2; this.node.scaleY = 2; this.node.setScale(2); this.node.setScale(2, 2);
-
更改尺寸
this.node.setContentSize(100, 100); this.node.setContentSize(cc.size(100, 100)); this.node.width = 100; this.node.height = 100;
-
更改锚点位置
this.node.anchorX = 1; this.node.anchorY = 0; this.node.setAnchorPoint(1, 0);
-
更改颜色和不透明度
假如我们有一个 Sprite 的实例为 mySprite,如果需要设置它的颜色:
mySprite.node.color = cc.Color.RED;
设置不透明度:
mySprite.node.opacity = 128;
5. 创建节点
创建新节点
var node = new cc.Node('Sprite');
var sp = node.addComponent(cc.Sprite);
sp.spriteFrame = this.sprite;
node.parent = this.node;
克隆已有节点
var node = cc.instantiate(this.target);
创建预制节点
和克隆已有节点相似,你可以设置一个预制(Prefab)并通过 cc.instantiate 生成节点
6. 销毁节点
通过 node.destroy()
函数,可以销毁节点。值得一提的是,销毁节点并不会立刻被移除,而是在当前帧逻辑更新结束后,统一执行。当一个节点销毁后,该节点就处于无效状态,可以通过 cc.isValid
判断当前节点是否已经被销毁。
六、动作系统
// 创建一个移动动作
var action = cc.moveTo(2, 100, 100);
// 执行动作
node.runAction(action);
// 停止一个动作
node.stopAction(action);
// 停止所有动作
node.stopAllActions();
动作类型
1. 基础动作
- cc.moveTo === 移动
- cc.rotateBy === 旋转
- cc.scaleTo === 缩放
2. 容器动作
-
cc.sequence === 顺序动作
// 让节点左右来回移动 var seq = cc.sequence(cc.moveBy(0.5, 200, 0), cc.moveBy(0.5, -200, 0)); node.runAction(seq);
-
cc.spawn === 同步动作
// 让节点在向上移动的同时缩放 var spawn = cc.spawn(cc.moveBy(0.5, 0, 50), cc.scaleTo(0.5, 0.8, 1.4)); node.runAction(spawn);
-
cc.repeat === 重复动作
// 让节点左右来回移动,并重复5次 var seq = cc.repeat( cc.sequence( cc.moveBy(2, 200, 0), cc.moveBy(2, -200, 0) ), 5); node.runAction(seq);
-
cc.repeatForever === 永远重复动作
// 让节点左右来回移动并一直重复 var seq = cc.repeatForever( cc.sequence( cc.moveBy(2, 200, 0), cc.moveBy(2, -200, 0) ));
-
cc.speed ===
3. 动作回调
var finished = cc.callFunc(this.myMethod, this, opt);
第一个参数是处理回调的方法,第二个参数指定了处理回调方法的 context(也就是绑定 this),第三个参数是向处理回调方法的传参。
var finished = cc.callFunc(function(target, score) {
this.score += score;
}, this, 100);//动作完成后会给玩家加100分
4. 缓动动作
不可以单独存在,它永远是为了修饰基础动作而存在的,它可以用来修改基础动作的时间曲线,让动作有快入、缓入、快出或其它更复杂的特效。需要注意的是,只有时间间隔动作才支持缓动:
var action = cc.scaleTo(0.5, 2, 2);
action.easing(cc.easeIn(3.0));
七、事件监听
-
监听事件
this.node.on('mousedown', function ( event ) { console.log('Hello!'); });
事件监听函数 on 可以传第三个参数 target,用于绑定响应函数的调用者。以下两种调用方式, 效果上是相同的:
// 使用函数绑定
this.node.on('mousedown', function ( event ) {
this.enabled = false;
}.bind(this));
// 使用第三个参数
this.node.on('mousedown', function (event) {
this.enabled = false;
}, this);
除了使用 on 监听,我们还可以使用 once
方法。once
监听在监听函数响应后就会关闭监听事件。
- 关闭监听
off 方法的 参数必须和 on 方法的参数一一对应,才能完成关闭。
onEnable: function () {
this.node.on('foobar', this._sayHello, this);
},
onDisable: function () {
this.node.off('foobar', this._sayHello, this);
},
- 发射事件
emit
和 dispatchEvent
。两者的区别在于,后者可以做事件传递。
this.node.emit('say-hello', {
msg: 'Hello, this is Cocos Creator',
});
- 系统内置事件
全局系统事件是指与节点树不相关的各种全局事件,由 cc.systemEvent
来统一派发,目前支持了以下几种事件:
1️⃣键盘事件
2️⃣设备重力传感事件
onLoad: function () {
// add key down and key up event
cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this);
cc.systemEvent.on(cc.SystemEvent.EventType.KEY_UP, this.onKeyUp, this);
},
onDestroy () {
cc.systemEvent.off(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this);
cc.systemEvent.off(cc.SystemEvent.EventType.KEY_UP, this.onKeyUp, this);
},
八、计时器
1. 开始一个计时器
component.schedule(function() {
// 这里的 this 指向 component
this.doSomething();
}, 5);
上面这个计时器将每隔 5s 执行一次.
// 以秒为单位的时间间隔
var interval = 5;
// 重复次数
var repeat = 3;
// 开始延时
var delay = 10;
component.schedule(function() {
// 这里的 this 指向 component
this.doSomething();
}, interval, repeat, delay);
上面的计时器将在10秒后开始计时,每5秒执行一次回调,重复3次。
2. 只执行一次的计时器
component.scheduleOnce(function() {
// 这里的 this 指向 component
this.doSomething();
}, 2);
上面的计时器将在两秒后执行一次回调函数,之后就停止计时.
3. 取消计时器
this.count = 0;
this.callback = function () {
if (this.count === 5) {
// 在第六次执行回调时取消这个计时器
this.unschedule(this.callback);
}
this.doSomething();
this.count++;
}
component.schedule(this.callback, 1);
下面是 Component 中所有关于计时器的函数:
- schedule:开始一个计时器
- scheduleOnce:开始一个只执行一次的计时器
- unschedule:取消一个计时器
- unscheduleAllCallbacks:取消这个组件的所有计时器
4. js定时器
var id = setTimeout("function",time)
设置一个超时对象
var id = setInterval("function",time)
设置一个超时对象
setInterval为自动重复,setTimeout不会重复。
clearTimeout(对象) 清除已设置的setTimeout对象
clearInterval(对象) 清除已设置的setInterval对象
给定时器调用传递参数
function say(_name){
console.log("hello,"+_name);
}
var hello_id1 = setTimeout(function(){
say('wade1')
},2000);
var hello_id2 = setInterval(function(){
say('wade2')
clearInterval(hello_id2)
hello_id2 = null
},3000);
九、网络
1. XMLHttpRequest
2. WebSocket
3. SocketIO