1、在IDE中创建脚本比较方便。由于大部分时间我们都是在编辑组件脚本,所以这里就围绕组件脚本来展开。
2、cocos creator中组件的使用方式一般是
(1)在预制件资源或场景资源中创建好节点node,然后把组件挂到node上,这是最常见的一种。
(2)在脚本编辑过程中,实例化组件,并挂到已知节点上。这种方式不常用,但有时候也是有必要的,比如‘女生快跑’中的人物和道具,需要动态的添加或删除,就没办法直接在场景资源中事先挂好了。另外,组件实例化过程中有一些细节,在(1)中已经让引擎处理了,但在这里需要我们自己处理。
(3)瞬间动态添加多个节点,容易造成性能问题,比如“植物大战海盗”中的listview,目前还没找到最佳优化方案。
3、类型声明,实例化
var Sprite = cc.Class({
name: "sprite",
ctor: function (typeStr) {//构造函数,
this.type = typeStr;
cc.log(this instanceof Sprite); // true
}
print: function () { //实例方法
cc.log(this instanceof Sprite);
}
});
var obj = new Sprite('typeStr');//实例化
注意:实例化需要传入参数时,就可以编辑构造函数,比如‘植物大战海盗’中的UIBuildingInfo、UIBuildingLvup和UITraining。但使用构造函数容易漏写new,不优雅,通常我们会专门写一个showWith方法或creatorwith方法来避免这种麻烦。
4、继承
var subSprite = cc.Class({
extends: Sprite,
ctor: function () {
cc.log("subSprite"); //不需要显式调用父类构造方法,cc.class内部已经自动实现了
}
});
var subSprite = new subSprite();//依次输出true和subSprite
当然,继承不是必须的,有时候我们就是可以设计一个工具类,不需要继承任何类,比如‘植物大战海盗’中的TimeFormat类。
5、声明属性:对于组件(其它的不行),我们有特殊的声明属性的方式,通过这种方式声明的属性,可以在IDE中看到对应的属性,就可以进行可视化编辑了。
cc.Class({
extends: cc.Component,
properties: {
userID: 20,
userName: "Foobar",
pos: cc.Vec2,
color: new cc.Color(255, 255, 255, 128),
strings: [cc.String],
score: {
default: 0,
displayName: "Score (player)",
tooltip: "The score of player",
},
width: {
get: function () {
return this._width;
},
set: function (value) {
this._width = value;
}
}
}
});
(1)当属性为基本的js类型时,可直接赋值默认值。
(2)若为引擎特有类型,则填写他们的构造函数
(3)当声明属性是一个数组时,可以在声明处填写他们的类型或构造函数来完成声明,
(4)自定义属性,需要完整的声明,如上面的score属性
(5)get/set方法也是很有用的
6、进行完整的属性声明时,有很多参数可以配置,最常用的有:
(1)default: 设置属性的默认值,这个默认值仅在组件第一次添加到节点上时才会用到
(2)type: 限定属性的数据类型,详见 CCClass 进阶参考:type 参数
(3)visible: 设为 false 则不在 属性检查器 面板中显示该属性
(4)serializable: 设为 false 则不序列化(保存)该属性
(5)displayName: 在 属性检查器 面板中显示成指定名字
(6)tooltip: 在 属性检查器 面板中添加属性的 Tooltip
(7)完整的,参考:http://docs.cocos.com/creator/manual/zh/scripting/reference/attributes.html
7、访问节点和组件:基础的就不说了,说几个用的少但很有用的
(1)访问组件所在节点的其它组件,我一般用this.node.getComponent(),其实组件自身也有这个功能,可以直接this.getComponent()。
(2)查找子节点一般用this.node.getChildByName(),如果子节点的层次较深,你还可以使用 cc.find("Cannon 01/Barrel/SFX", this.node)。注意,当 cc.find 只传入第一个参数时,将从场景根节点开始逐级查找,如:cc.find("Canvas/Menu/Back");
8、访问已有变量的值,有两种形式:通过全局变量window,通过require模块来获取中的变量。当然,通过全局变量来访问会方便很多,‘植物大战僵尸’里就有不少例子。
9、关于模块的编辑:最重要的一点就是,要使用module.exports导出变量
10、声明周期:http://docs.cocos.com/creator/manual/zh/scripting/life-cycle-callbacks.html
(1)主要包括ctor、onLoad、start、update等
(2)参考我在UITraining、ViewCommon中的做法,我人为的添加了几个生命周期阶段,用于处理进出场动画问题。
11、节点的创建和销毁:
(1)脚本中动态创建脚本:‘女神快跑’中的actor就是用的这种方式
createTestNode: function () {
var node = new cc.Node('SpriteNode');
var sp = node.addComponent(cc.Sprite);
sp.spriteFrame = this.sprite;
node.parent = this.node;
},
(2)克隆已有节点:‘女神快跑’中的actor使用这种方式也许还会简单些
properties: {
target: {
default: null,
type: cc.Node,
},
},
start: function () {
var scene = cc.director.getScene();
var node = cc.instantiate(this.target);
node.parent = scene;
node.setPosition(0, 0);
},
(3)通过预制件创建节点:最常用,不多说
(4)如果一个节点不再使用了,请直接调用它的 destroy 而不是 removeFromParent
12、资源获取和加载
(1)Assert资源:Creator 提供了名为 "Asset" 的资源类型,cc.SpriteFrame, cc.AnimationClip, cc.Prefab 等资源都属于 Asset。Asset 的加载是统一并且自动化的,相互依赖的 Asset 能够被自动预加载。
(2)Cocos2d 的一些旧 API 并没有使用上面提到的 Asset 对象,而是直接用 URL 字符串指代资源。为了兼容这些 API,我们把这类资源叫做 "Raw Asset"。图片(cc.Texture2D),声音(cc.AudioClip),粒子(cc.ParticleAsset)等资源都是 Raw Asset。Raw Asset 在脚本里由一个 url 字符串来表示,当你要在引擎中使用 Raw Asset,只要把 url 传给引擎的 API,引擎内部会自动加载这个 url 对应的资源。
cc.Class({
extends: cc.Component,
properties: {
textureURL: {
default: "",
url: cc.Texture2D //注意,这里用的url,不是type
}
}
});
(3)不论是 Asset 还是 Raw Asset,只要在脚本中定义好类型,就能直接在 属性检查器 很方便地设置资源
(4)通过脚本动态加载:要注意两点,一是所有需要通过脚本动态加载的资源,都必须放置在 resources 文件夹或它的子文件夹下。resources 需要在 assets 文件夹中手工创建,并且必须位于 assets 的根目录。第二个要注意的是 Creator 相比之前的 Cocos2d-html5,资源动态加载的时都是异步的,需要在回调函数中获得载入的资源。另外,动态加载两种资源的方式有所不同,参考:http://docs.cocos.com/creator/manual/zh/scripting/load-assets.html
13、资源的释放:
(1)在加载完资源之后,所有的资源都会临时被缓存到 cc.loader 中,以避免重复加载资源时发送无意义的 http 请求,当然,缓存的内容都会占用内存,有些资源可能用户不再需要了,想要释放它们。
(2)由于js无法跟踪对象引用,我们只能根据游戏逻辑来选择资源释放的时机。
14、事件监听和发射:
(1)普通监听:this.node.on('mousedown', function ( event ){})
(2)监听到一次就关闭监听:this.node.once('mousedown', function ( event ){})
(3)关闭监听:this.node.off('say-hello', this.sayHello, this)
(4)发射事件:this.node.emit('say-hello', { msg: 'Hello, this is Cocos Creator'});
(5)派送事件:dispatchEvent 方法,通过该方法发射的事件,会进入事件派送阶段。在 Cocos Creator 的事件派送系统中,我们采用冒泡派送的方式。冒泡派送会将事件从事件发起节点,不断地向上传递给他的父级节点,直到到达根节点或者在某个节点的响应函数中做了中断处理 event.stopPropagation()。
派送:this.node.dispatchEvent( new cc.Event.EventCustom('foobar', true) );
中断处理:this.node.on('foobar', function (event) {event.stopPropagation();});
(6)系统内置事件:http://docs.cocos.com/creator/manual/zh/scripting/internal-events.html
(7)玩家输入事件:http://docs.cocos.com/creator/manual/zh/scripting/player-controls.html
15、动作:http://docs.cocos.com/creator/manual/zh/scripting/actions.html
需要注意的是,动作系统并不能取代动画系统,动作系统提供的是面向程序员的 API 接口,而动画系统则是提供在编辑器中来设计的。同时,他们服务于不同的使用场景,动作系统比较适合来制作简单的形变和位移动画,而动画系统则强大许多,美术可以用编辑器制作支持各种属性,包含运动轨迹和缓动的复杂动画。
16、计时器:之前都用setTimeout 和 setInterval,其实cc.Scheduler更加强大好用
17、对象池:http://docs.cocos.com/creator/manual/zh/scripting/pooling.html,聊天界面的cell复用,其实就是用了对象池的思想,现在可以着手换成好用的对象池了。