CocosCreator基础
- CocosCreator项目结构:
- CocosCreator 小Tips
- 1.Cos中的skew(倾斜角挺有意思的),
- 2.Cos引擎中require("../");会直接让你去选择文件路径
- 3.cc.director.loadScene("场景名"); 加载场景
- 4.调用声音引擎播放声音
- 5.c.callFunc() ;--重/回调函数
- 6.动作系统
- 7.事件系统:
- 8.如何用插件控制 Prefab?
- 9.对齐节点
- 10.Cos中的生命周期函数:
- 11.创建和销毁节点
- 12.常驻节点
- 13.预加载场景
- 14.动态加载资源
- 15.JavaScript中无法跟踪对象引用。// 这也就是无法实现vs中三斜杠注释/// 的原因吧。
- 16.JavaScript中的垃圾回收机制是延迟的。
- 17.监听和发射事件
- 18.系统内置事件--节点系统时间
- 19.动作系统
- 20.使用计时器--//延时函数
- 21.脚本执行顺序
- 22.网络接口
- 23.对象池--:
- 24.模块化脚本
- 25.分包加载 --//未实际在项目中使用。 后面有2.4x bundle的使用
- 26.插件脚本--插件脚本通常用于引入第三方库。目前仅支持 JavaScript 插件脚本
- 27.数据的保存和读写--json
- 28.cocos 调整同一父节点下子节点顺序
- 29.//触摸移动节点 + 键盘输入事件
- 30*编辑器自定义属性面板
- 31 拓展系统
修改时间 | 版本 | 简介 |
---|---|---|
2022年12月7日 | 1.0 | 整理笔记 |
-
CocosCreator基础
参考官方文档,快速入门总结。 https://docs.cocos.com/creator/2.2/manual/zh/ -
本文档大部分更新基于2.x版本,后续更新使用2.4x版本,差异部分需注意。
CocosCreator项目结构:
资源文件夹(assets)
assets 将会用来放置您游戏中所有本地资源、脚本和第三方库文件。只有在 assets 目录下的内容才能显示在 资源管理器 中。assets 中的每个文件在导入项目后都会生成一个相同名字的 .meta 文件,用于存储该文件作为资源导入后的信息和与其他资源的关联。一些第三方工具生成的工程或设计原文件,如 TexturePacker 的 .tps 文件,或 Photoshop 的 .psd 文件,可以选择放在 assets 外面来管理。
资源库(library)
library 是将 assets 中的资源导入后生成的,在这里文件的结构和资源的格式将被处理成最终游戏发布时需要的形式。如果您使用版本控制系统管理您的项目,这个文件夹是不需要进入版本控制的。
当 library 丢失或损坏的时候,只要删除整个 library 文件夹再打开项目,就会重新生成资源库。
本地设置(local)
local 文件夹中包含该项目的本地设置,包括编辑器面板布局,窗口大小,位置等信息。您不需要关心这里的内容,只要按照您的习惯设置编辑器布局,这些就会自动保存在这个文件夹。一般 local 也不需要进入版本控制。
项目设置(settings)
settings 里保存项目相关的设置,如 构建发布 菜单里的包名、场景和平台选择等。这些设置需要和项目一起进行版本控制。
project.json
project.json 文件和 assets 文件夹一起,作为验证 Cocos Creator 项目合法性的标志。只有包括了这两个内容的文件夹才能作为 Cocos Creator 项目打开。而 project.json 本身目前只用来规定当前使用的引擎类型和插件存储位置,不需要用户关心其内容。
这个文件也应该纳入版本控制。
构建目标(build)
在使用主菜单中的 项目 -> 构建发布... 使用默认发布路径发布项目后,编辑器会在项目路径下创建 build目录,并存放所有目标平台的构建工程。由于每次发布项目后资源 id 可能会变化,而且构建原生工程时体积很大,所以此目录建议不进入版本控制。
来源: https://docs.cocos.com/creator/manual/zh/getting-started/project-structure.html
CocosCreator 小Tips
*CocosCreator中删除资源是无法复原的。。。
获取一个uuid值:
//var a= require('node-uuid').v4();
// document.write(a);
1.Cos中的skew(倾斜角挺有意思的),
2.Cos引擎中require("../");会直接让你去选择文件路径
eg: var ZJHMgr = require("../zjh/zjh_GameMgr").ZJHGameMgr;
就用一个require("./r"); //是找同级目录下的文件
3.cc.director.loadScene("场景名"); 加载场景
cc.director 是一个管理你的游戏逻辑流程的单例对象。
4.调用声音引擎播放声音
cc.audioEngine.playEffect(this.jumpAudio, false);
5.c.callFunc() ;--重/回调函数
cc.callFunc = function (selector, selectorTarget, data) {
return new cc.CallFunc(selector, selectorTarget, data);
};
我们可以看到 callFunc 方法可以传入三个参数,第一个参数是方法的 selector,我们可以理解为方法名。第二个参数是 Object 类型,一般填入 this。第三个参数为带回的数据,可以是所有的数据类型,可以不填。我们再注意到这个方法的返回值 —— ActionInstant,这是一个瞬间执行的动作类。到这里我们就可以理解了,使用 callFunc 调用回调函数可以让函数转变为 cc 中的 Action(动作),这一用法在 cc 的动作系统里非常实用!例如在上面我们将播放声音的函数传入 callFunc 赋值给 callback,让 callback 成为了一个播放声音的动作 Action,那么我们之后就能通过 cc.sequence 将跳跃和播放声音的动作组合起来,实现每跳一次就能播放音效的功能!
来源: https://docs.cocos.com/creator/manual/zh/getting-started/quick-start.html
6.动作系统
cc.sequence();--组合动作
7.事件系统:
1. node.emit(type, detail):通知所有监听 type 事件的监听器,可以发送一个附加参数。
2. node.dispatchEvent(event):发送一个事件给它的监听器,支持冒泡。
3. node.on(type, callback, target):持续监听 node 的 type 事件。
4. node.once(type, callback, target):监听一次 node 的 type 事件。
5. node.off(type, callback, target):取消监听所有 type 事件或取消 type 的某个监听器(用 callback 和 target 指定)。
6. 来源: https://docs.cocos.com/creator/manual/zh/getting-started/cocos2d-x-guide.html
8.如何用插件控制 Prefab?
创建 Prefab:
Editor.Ipc.sendToPanel('scene', 'scene:create-prefab', node.uuid, 'db://assets/xxx/xxx.prefab');
进入 Prefab 编辑模式:
Editor.Ipc.sendToAll('scene:enter-prefab-edit-mode', assetUuid);
保存 Prefab:
Editor.Ipc.sendToPanel('scene', 'scene:apply-prefab', node.uuid);
来源: https://docs.cocos.com/creator/manual/zh/getting-started/faq.html
9.对齐节点
场景编辑器 左上角有一排按钮可以用来在选中多个节点时对齐这些节点,具体的对齐规则如下:
//本地图片
假设三个 Label 节点都已经选中,从左到右的对齐按钮会依次将这些节点:
- 按照最靠近上面的边界对齐
- 按照整体的水平中线对齐
- 按照最靠近下面的边界对齐
- 按照最靠近左边的边界对齐
- 按照整体的垂直中线对齐
- 按照最靠近右边的边界对齐
要注意对齐操作不管是一开始测定左右边界和中线还是之后将每个节点对齐时的参照,都是节点约束框的中心或某条边界,而不是节点的位置坐标。比如下图中我们将三个宽度不同的 Label 节点向右对齐后,得到下图中三个节点约束框的右边界对齐的情况,而不是让三个节点位置里的 x 坐标变成一致。
//本地图片
来源: https://docs.cocos.com/creator/manual/zh/content-workflow/scene-editing.html
10.Cos中的生命周期函数:
- onLoad 组件脚本的初始化阶段,我们提供了 onLoad 回调函数。onLoad 回调会在节点首次激活时触发,比如所在的场景被载入,或者所在节点被激活的情况下。在 onLoad 阶段,保证了你可以获取到场景中的其他节点,以及节点关联的资源数据。onLoad 总是会在任何 start 方法调用前执行,这能用于安排脚本的初始化顺序。通常我们会在 onLoad 阶段去做一些初始化相关的操作
- start:会在组件第一次激活前,也就是第一次执行 update 之前触发
- update
- lateUpdate
- onDestroy:当组件或者所在节点调用了 destroy(),则会调用 onDestroy 回调,并在当帧结束时统一回收组件
- onEnable:当组件的 enabled 属性从 false 变为 true 时,或者所在节点的 active 属性从 false 变为 true时,会激活 onEnable 回调。倘若节点第一次被创建且 enabled 为 true,则会在 onLoad 之后,start 之前被调用。
- onDisable:当组件的 enabled 属性从 true 变为 false 时,或者所在节点的 active 属性从 true 变为 false时,会激活 onDisable 回调
11.创建和销毁节点
创建新节点
除了通过场景编辑器创建节点外,我们也可以在脚本中动态创建节点。通过 new cc.Node() 并将它加入到场景中,可以实现整个创建过程。
以下是一个简单的例子:
cc.Class({
extends: cc.Component,
properties: {
sprite: {
default: null,
type: cc.SpriteFrame,
},
},
start: function () {
var node = new cc.Node('Sprite');
var sp = node.addComponent(cc.Sprite);
sp.spriteFrame = this.sprite;
node.parent = this.node;
},
});
克隆已有节点
有时我们希望动态的克隆场景中的已有节点,我们可以通过 cc.instantiate 方法完成。使用方法如下:
cc.Class({
extends: cc.Component,
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);
},
});
创建预制节点
和克隆已有节点相似,你可以设置一个预制(Prefab)并通过 cc.instantiate 生成节点。使用方法如下:
cc.Class({
extends: cc.Component,
properties: {
target: {
default: null,
type: cc.Prefab,
},
},
start: function () {
var scene = cc.director.getScene();
var node = cc.instantiate(this.target);
node.parent = scene;
node.setPosition(0, 0);
},
});
销毁节点
通过 node.destroy() 函数,可以销毁节点。值得一提的是,销毁节点并不会立刻被移除,而是在当前帧逻辑更新结束后,统一执行。当一个节点销毁后,该节点就处于无效状态,可以通过 cc.isValid 判断当前节点是否已经被销毁。
使用方法如下:
cc.Class({
extends: cc.Component,
properties: {
target: cc.Node,
},
start: function () {
// 5 秒后销毁目标节点
setTimeout(function () {
this.target.destroy();
}.bind(this), 5000);
},
update: function (dt) {//dt是两帧之间的时间间隔,单位秒
if (cc.isValid(this.target)) {
this.target.rotation += dt * 10.0;
}
},
});
来源: https://docs.cocos.com/creator/manual/zh/scripting/create-destroy.html
12.常驻节点
通过常驻节点进行场景资源管理和参数传递
引擎同时只会运行一个场景,当切换场景时,默认会将场景内所有节点和其他实例销毁。如果我们需要用一个组件控制所有场景的加载,或在场景之间传递参数数据,就需要将该组件所在节点标记为「常驻节点」,使它在场景切换时不被自动销毁,常驻内存。我们使用以下接口:
cc.game.addPersistRootNode(myNode);
上面的接口会将 myNode 变为常驻节点,这样挂在上面的组件都可以在场景之间持续作用,我们可以用这样的方法来储存玩家信息,或下一个场景初始化时需要的各种数据。
如果要取消一个节点的常驻属性:
cc.game.removePersistRootNode(myNode);
需要注意的是上面的 API 并不会立即销毁指定节点,只是将节点还原为可在场景切换时销毁的节点。
13.预加载场景
cc.director.loadScene 会在加载场景之后自动切换运行新场景,有些时候我们需要在后台静默加载新场景,并在加载完成后手动进行切换。那就可以预先使用 preloadScene 接口对场景进行预加载:
cc.director.preloadScene("table", function () {
cc.log("Next scene preloaded");
});
之后在合适的时间调用 loadScene, 就可以真正切换场景。
cc.director.loadScene("table");
就算预加载还没完成,你也可以直接调用 cc.director.loadScene,预加载完成后场景就会启动。实战例子
14.动态加载资源
cc.loader.loadRes(); //必须放在assets下的resourecs中;
如果一份资源仅仅是被 resources 中的其它资源所依赖,而不需要直接被 cc.loader.loadRes 调用,那么 请不要 放在 resources 文件夹里。
- bundle的未在此。
15.JavaScript中无法跟踪对象引用。// 这也就是无法实现vs中三斜杠注释/// 的原因吧。
16.JavaScript中的垃圾回收机制是延迟的。
17.监听和发射事件
监听事件
事件处理是在节点(cc.Node)中完成的。对于组件,可以通过访问节点 this.node 来注册和监听事件。监听事件可以 通过 this.node.on() 函数来注册,方法如下:
cc.Class({
extends: cc.Component,
properties: {
},
onLoad: function () {
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 方法关闭对应的监听事件。需要注意的是,off 方法的 参数必须和 on 方法的参数一一对应,才能完成关闭。
我们推荐的书写方法如下:
cc.Class({
extends: cc.Component,
_sayHello: function () {
console.log('Hello World');
},
onEnable: function () {
this.node.on('foobar', this._sayHello, this);
},
onDisable: function () {
this.node.off('foobar', this._sayHello, this);
},
});
发射事件
我们可以通过两种方式发射事件:emit 和 dispatchEvent。两者的区别在于,后者可以做事件传递。 我们先通过一个简单的例子来了解 emit 事件:
cc.Class({
extends: cc.Component,
onLoad () {
// args are optional param.
this.node.on('say-hello', function (msg) {
console.log(msg);
});
},
start () {
// At most 5 args could be emit.
this.node.emit('say-hello', 'Hello, this is Cocos Creator');
},
});
事件参数说明
在 2.0 之后,我们优化了事件的参数传递机制。 在发射事件时,我们可以在 emit 函数的第二个参数开始传递我们的事件参数。同时,在 on 注册的回调里,可以获取到对应的事件参数。
cc.Class({
extends: cc.Component,
onLoad () {
this.node.on('foo', function (arg1, arg2, arg3) {
console.log(arg1, arg2, arg3); // print 1, 2, 3
});
},
start () {
let arg1 = 1, arg2 = 2, arg3 = 3;
// At most 5 args could be emit.
this.node.emit('foo', arg1, arg2, arg3);
},
});
需要说明的是,出于底层事件派发的性能考虑,这里最多只支持传递 5 个事件参数。所以在传参时需要注意控制参数的传递个数。
派送事件
上文提到了 dispatchEvent 方法,通过该方法发射的事件,会进入事件派送阶段。在 Cocos Creator 的事件派送系统中,我们采用冒泡派送的方式。冒泡派送会将事件从事件发起节点,不断地向上传递给他的父级节点,直到到达根节点或者在某个节点的响应函数中做了中断处理 event.stopPropagation()。
//本地图片
如上图所示,当我们从节点 c 发送事件 “foobar”,倘若节点 a,b 均做了 “foobar” 事件的监听,则 事件会经由 c 依次传递给 b,a 节点。如:
// 节点 c 的组件脚本中
this.node.dispatchEvent( new cc.Event.EventCustom('foobar', true) );
如果我们希望在 b 节点截获事件后就不再将事件传递,我们可以通过调用 event.stopPropagation() 函数来完成。具体方法如下:
// 节点 b 的组件脚本中
this.node.on('foobar', function (event) {
event.stopPropagation();
});
请注意,在发送用户自定义事件的时候,请不要直接创建 cc.Event 对象,因为它是一个抽象类,请创建 cc.Event.EventCustom 对象来进行派发。
事件对象
在事件监听回调中,开发者会接收到一个 cc.Event 类型的事件对象 event,stopPropagation 就是 cc.Event 的标准 API,其它重要的 API 包含:
API 名 | 类型 | 意义 |
---|---|---|
type | String | 事件的类型(事件名) |
target | cc.Node | 接收到事件的原始对象 |
currentTarget | cc.Node | 接收到事件的当前对象,事件在冒泡阶段当前对象可能与原始对象不同 |
getType | Function | 获取事件的类型 |
stopPropagation | Function | 停止冒泡阶段,事件将不会继续向父节点传递,当前节点的剩余监听器仍然会接收到事件 |
stopPropagationImmediate | Function | 立即停止事件的传递,事件将不会传给父节点以及当前节点的剩余监听器 |
getCurrentTarget | Function | 获取当前接收到事件的目标节点 |
detail | Function | 自定义事件的信息(属于 cc.Event.EventCustom) |
setUserData | Function | 设置自定义事件的信息(属于 cc.Event.EventCustom) |
getUserData | Function | 获取自定义事件的信息(属于 cc.Event.EventCustom) |
完整的 API 列表可以参考 cc.Event 及其子类的 API 文档。
18.系统内置事件--节点系统时间
cc.Node 有一套完整的事件监听和分发机制。在这套机制之上,我们提供了一些基础的节点相关的系统事件,这篇文档将介绍这些事件的使用方式。
Cocos Creator 支持的系统事件包含鼠标、触摸、键盘、重力传感四种,其中本章节重点介绍与节点树相关联的鼠标和触摸事件,这些事件是被直接触发在相关节点上的,所以被称为节点系统事件。与之对应的,键盘和重力传感事件被称为全局系统事件,细节可以参考全局系统事件文档。
系统事件遵守通用的注册方式,开发者既可以使用枚举类型也可以直接使用事件名来注册事件的监听器,事件名的定义遵循 DOM 事件标准。
来源: https://docs.cocos.com/creator/manual/zh/scripting/internal-events.html
19.动作系统
Cocos Creator 提供的动作系统源自 Cocos2d-x,API 和使用方法均一脉相承。动作系统可以在一定时间内对节点完成位移,缩放,旋转等各种动作。
需要注意的是,动作系统并不能取代 动画系统,动作系统提供的是面向程序员的 API 接口,而动画系统则是提供在编辑器中来设计的。同时,他们服务于不同的使用场景,动作系统比较适合来制作简单的形变和位移动画,而动画系统则强大许多,美术可以用编辑器制作支持各种属性,包含运动轨迹和缓动的复杂动画。
来源: https://docs.cocos.com/creator/manual/zh/scripting/actions.html
20.使用计时器--//延时函数
在 Cocos Creator 中,我们为组件提供了方便的计时器,这个计时器源自于 Cocos2d-x 中的 cc.Scheduler,我们将它保留在了 Cocos Creator 中并适配了基于组件的使用方式。
也许有人会认为 setTimeout 和 setInterval 就足够了,开发者当然可以使用这两个函数,不过我们更推荐使用计时器,因为它更加强大灵活,和组件也结合得更好!
下面来看看它的具体使用方式:
来源: https://docs.cocos.com/creator/manual/zh/scripting/scheduler.html
21.脚本执行顺序
- 使用统一的控制脚本来初始化其他脚本
一般我都会有一个 Game.js 的脚本作为总的控制脚本,假如我还有 Player.js, Enemy.js, Menu.js 三个组件,那么他们的初始化过程是这样的:
// Game.js
const Player = require('Player');
const Enemy = require('Enemy');
const Menu = require('Menu');
cc.Class({
extends: cc.Component,
properties: {
player: Player,
enemy: Enemy,
menu: Menu
},
onLoad: function () {
this.player.init();
this.enemy.init();
this.menu.init();
}
});
其中在 Player.js, Enemy.js 和 Menu.js 中需要实现 init 方法,并将初始化逻辑放进去。这样我们就可以保证 Player, Enemy 和 Menu 的初始化顺序。
- 在 Update 中用自定义方法控制更新顺序
--就是在update中按顺序执行方法
同理如果要保证以上三个脚本的每帧更新顺序,我们也可以将分散在每个脚本里的 update 替换成自己定义的方法:
// Player.js
updatePlayer: function (dt) {
// do player update
}
然后在 Game.js 脚本的 update 里调用这些方法:
// Game.js
update: function (dt) {
this.player.updatePlayer(dt);
this.enemy.updateEnemy(dt);
this.menu.updateMenu(dt);
}
- 控制同一个节点上的组件执行顺序--
--就是在属性面板中把脚本顺序调整
- 设置组件执行优先级
如果以上方法还是不能提供所需的控制粒度,还可以直接设置组件的 executionOrder。executionOrder 会影响组件的生命周期回调的执行优先级。设置方法如下:
// Player.js
cc.Class({
extends: cc.Component,
editor: {
executionOrder: -1
},
onLoad: function () {
cc.log('Player onLoad!');
}
});
executionOrder 越小,该组件相对其它组件就会越先执行。executionOrder 默认为 0,因此设置为负数的话,就会在其它默认的组件之前执行。 executionOrder 只对 onLoad, onEnable, start, update 和 lateUpdate 有效,对 onDisable 和 onDestroy 无效。
22.网络接口
在 Cocos Creator 中,我们支持 Web 平台上最广泛使用的标准网络接口:
- XMLHttpRequest:用于短连接
- WebSocket:用于长连接
当然,在 Web 平台,浏览器原生就支持这两个接口,之所以说 Cocos Creator 支持,是因为在发布原生版本时,用户使用这两个网络接口的代码也是可以运行的。也就是遵循 Cocos 一直秉承的 “一套代码,多平台运行” 原则。
来源: https://docs.cocos.com/creator/manual/zh/scripting/network.html
23.对象池--:
对象池的概念
对象池就是一组可回收的节点对象,我们通过创建 cc.NodePool 的实例来初始化一种节点的对象池。通常当我们有多个 prefab 需要实例化时,应该为每个 prefab 创建一个 cc.NodePool 实例。 当我们需要创建节点时,向对象池申请一个节点,如果对象池里有空闲的可用节点,就会把节点返回给用户,用户通过 node.addChild 将这个新节点加入到场景节点树中。
当我们需要销毁节点时,调用对象池实例的 put(node) 方法,传入需要销毁的节点实例,对象池会自动完成把节点从场景节点树中移除的操作,然后返回给对象池。这样就实现了少数节点的循环利用。 假如玩家在一关中要杀死 100 个敌人,但同时出现的敌人不超过 5 个,那我们就只需要生成 5 个节点大小的对象池,然后循环使用就可以了。
来源: https://docs.cocos.com/creator/manual/zh/scripting/pooling.html
对象池使用 1、new 一个 nodepool 2、get一下对象池看看是否为空 3、put一个预制体/节点啥的
24.模块化脚本
Cocos Creator 允许你将代码拆分成多个脚本文件,并且让它们相互调用。要实现这点,你需要了解如何在 Cocos Creator 中定义和使用模块,这个步骤简称为模块化。
如果你还不确定模块化究竟能做什么,模块化相当于:
- Java 和 Python 中的 import
- C# 中的 using
- C/C++ 中的 include
- HTML 中的
模块化使你可以在 Cocos Creator 中引用其它脚本文件:
- 访问其它文件导出的参数
- 调用其它文件导出的方法
- 使用其它文件导出的类型
- 使用或继承其它 Component
Cocos Creator 中的 JavaScript 使用和 Node.js 几乎相同的 CommonJS 标准来实现模块化,简单来说:
- 每一个单独的脚本文件就构成一个模块
- 每个模块都是一个单独的作用域
- 以同步的 require 方法来引用其它模块
- 设置 module.exports 为导出的变量
- 来源: https://docs.cocos.com/creator/manual/zh/scripting/modular-script.html
25.分包加载 --//未实际在项目中使用。 后面有2.4x bundle的使用
随着游戏玩法越来越丰富,游戏的代码量也越来越大,开发者对于扩大包大小的需求越来越强烈,同时微信小游戏也支持了分包加载的功能。所以 Cocos Creator 推出了 分包加载 这样一个功能,该功能支持 代码 和 资源 的分包加载。其中 资源分包 从 v2.0.7 开始支持。分包加载目前只支持各类小游戏平台,如微信小游戏、OPPO 小游戏等。
分包加载,即把游戏内容按一定规则拆分在几个包里,在首次启动的时候只下载必要的包,这个必要的包称为 主包,开发者可以在主包内触发下载其他子包,这样可以有效降低首次启动的消耗时间。
来源: https://docs.cocos.com/creator/manual/zh/scripting/subpackage.html
26.插件脚本--插件脚本通常用于引入第三方库。目前仅支持 JavaScript 插件脚本
来源:https://docs.cocos.com/creator/manual/zh/scripting/plugin-scripts.html
27.数据的保存和读写--json
存储和读取用户数据
我们在游戏中通常需要存储用户数据,如音乐开关、显示语言等,如果是单机游戏还需要存储玩家存档。 Cocos Creator 中我们使用 cc.sys.localStorage 接口来进行用户数据存储和读取的操作。
cc.sys.localStorage 接口是按照 Web Storage API 来实现的,在 Web 平台运行时会直接调用 Web Storage API,在原生平台上会调用 sqlite 的方法来存储数据。一般用户不需要关心内部的实现。
配合本篇文档可以参考 数据存储范例。
存储数据
cc.sys.localStorage.setItem(key, value)
上面的方法需要两个参数,用来索引的字符串键值 key,和要保存的字符串数据 value。
假如我们要保存玩家持有的金钱数,假设键值为 gold:
cc.sys.localStorage.setItem('gold', 100);
对于复杂的对象数据,我们可以通过将对象序列化为 JSON 后保存:
userData = {
name: 'Tracer',
level: 1,
gold: 100
};
cc.sys.localStorage.setItem('userData', JSON.stringify(userData));
读取数据
cc.sys.localStorage.getItem(key)
和 setItem 相对应,getItem 方法只要一个键值参数就可以取出我们之前保存的值了。对于上文中储存的用户数据:
var userData = JSON.parse(cc.sys.localStorage.getItem('userData'));
移除键值对
当我们不再需要一个存储条目时,可以通过下面的接口将其移除:
cc.sys.localStorage.removeItem(key)
简单数据加密
对于单机游戏来说,对玩家存档进行加密可以延缓游戏被破解的时间。要加密存储数据,只要在将数据通过JSON.stringify 转化为字符串后调用你选中的加密算法进行处理,再将加密结果传入 setItem 接口即可。
您可以搜索并选择一个适用的加密算法和第三方库,比如 encryptjs, 将下载好的库文件放入你的项目,存储时:
var encrypt=require('encryptjs');
var secretkey= 'open_sesame'; // 加密密钥
var dataString = JSON.stringify(userData);
var encrypted = encrypt.encrypt(dataString,secretkey,256);
cc.sys.localStorage.setItem('userData', encrypted);
读取时:
var cipherText = cc.sys.localStorage.getItem('userData');
var userData=JSON.parse(encrypt.decrypt(cipherText,secretkey,256));
注意 数据加密不能保证对用户档案的完全掌控,如果您需要确保游戏存档不被破解,请使用服务器进行数据存取。
来源: https://blog.csdn.net/qq_33663319/article/details/79663222
Cocos Creator中cc.sys.localStorage保存数据的位置
:https://blog.csdn.net/qq_43248007/article/details/87353511
28.cocos 调整同一父节点下子节点顺序
2018-11-02 12:12:25 t_z_l 阅读数 1983
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_41316824/article/details/83653262
同一父节点下层级高的显示在前面
设置层级
var index = 1;
this.node.setSiblingIndex(index);
获取所在的层级
this.node.getSiblingIndex();
29.//触摸移动节点 + 键盘输入事件
/
startPos:any;
onLoad () {
this.node.on(cc.Node.EventType.TOUCH_START,function(event){
this.startPos = this.node.position;
this.node.on(cc.Node.EventType.TOUCH_MOVE,this.move,this);
event.stopPropagation(); //停止冒泡事件派发
},this);
this.node.on(cc.Node.EventType.TOUCH_END,function(event){
this.node.off(cc.Node.EventType.TOUCH_MOVE,this.move,this);
},this);
this.node.on(cc.Node.EventType.TOUCH_CANCEL,function(event){
this.node.off(cc.Node.EventType.TOUCH_MOVE,this.move,this);
},this);
cc.systemEvent.on(cc.SystemEvent.EventType.KEY_UP,this.OnKeyDown,this);
}
move(event){
let touch = event.getTouches();
let touPos = touch[0].getLocation();
let touStartPos = touch[0].getStartLocation();
let detlaPos =cc.v2(touPos.x - touStartPos.x, touPos.y - touStartPos.y);
this.node.setPosition(this.startPos.add(detlaPos));
}
OnKeyDown(event){
switch(event.keyCode){
case cc.KEY.a: cc.log('aaaa');break;
default:break;
}
}
30*编辑器自定义属性面板
参考: https://juejin.cn/post/6854573220595499015
31 拓展系统
后续拔高可了解-插件的拓展 “Electron”--“electronjs”,“vue”
https://www.electronjs.org/fiddle
http://docs.cocos.com/creator/3.0/manual/zh/editor/extension/package.html