cocos creater 学习笔记


第一章 界面
第二章 程序
第三章 发布

http://docs.cocos.com/creator/manual/zh/scripting/scheduler.html38
https://wenku.baidu.com/view/da3a94ea16fc700abb68fcec.html?from_page=view&from_mod=download21

第一章 界面
1.预制体;
把层级管理器中的节点拖进资源管理器中就创建了预制体;

2.运行调试:
cc.log输出信息,在网页上运行时,按F12,COSONLE面板里会显示; 

3.九宫格:
资源管理器选择图片---属性面板点编辑按钮,就可以编辑4个角;
节点的属性面板---sprite组件----type设置成sliced;就可以任意拉申了;

4.自适分辨率:
节点---添加widget组件,修改其属性就可以自适对齐;

第二章 程序

一.脚本文件
1.websocket 网络通信
var ws = new WebSocket(“ws://localhost:8080”); //申请一个WebSocket对象,(ws://IP:端口),
同http协议使用http://开头一样,WebSocket协议的URL使用ws://开头,另外安全的WebSocket协议使用wss://开头。
端口用80或者8080,8000;
6000和9000连接不上;

ws.send(“hello”);用于叫消息发送到服务端
ws.onopen = function() { console.log(“open”)}; //当websocket创建成功时,即会触发onopen事件
ws.onmessage = function(evt) { console.log(evt.data) }; //收到消息时,会触发onmessage事件,参数evt.data中包含server传输过来的数据

ws.onclose = function(evt) { console.log(“WebSocketClosed!”); };//收到关闭连接的请求时,触发onclose事件
ws.onerror = function(evt) { console.log(“WebSocketError!”); };//连接,处理,接收,发送数据失败会触发onerror事件

2.javascript的注意
教程:http://javascript.ruanyifeng.com/
教程: http://bonsaiden.github.io/JavaScript-Garden/zh/23

1)数组
a = [123, 456, 789];
a.push(25); //数组可增加;有自己的函数;

var list = [1, 2, 3, 4, 5, ...... 100000000];
for(var i = 0, l = list.length; i < l; i++) { console.log(list[i]); }

b: [
{
name: "Johnny",
email: "[email protected]"
},
{
name: "Nantas",
email: "[email protected]"
}
]

2).调用父类函数
var Shape = cc.Class({
getName: function () {
return "shape";
}
});

var Rect = cc.Class({
extends: Shape,
getName: function () {
var baseName = this._super(); //调用父类函数
//var baseName = Shape.prototype.getName.call(this); //调用父类函数
return baseName + " (rect)";
}
});

var obj = new Rect();
cc.log(obj.getName()); // "shape (rect)"

2.脚本
1.创建,添加,查找
创建:资源管理器---右键--新建javascript;
场景中元件添加脚本:选中元件---属性面板---添加组件---添加用户脚本组件;
显示脚本在哪些元件上调用过:右键脚本----在层级管里器中显示, 层级管里器中就会显示所有元件;只要不勾选就不会执行;

1.创建类:
1).创建继承自组件的类:
var AA=cc.Class({ //var声明变量,泛型变量
extends: cc.Component, //extends:表示继承组件类
properties: { //属性,可以显示到属性面版里,以 _ 开头的不显示
name:”dsdds”, //可以直接赋值;以开头的不显示
m_ws:WebSocket, //可以定义成类的对象
m_nod: { //可以定义成类的对象
default: null, //默认值
type: cc.Node //类型
}

    values: [cc.Vec2],                  //定义成数组[]是类型不是大小;
    score: {                         //可以设置面板里的属性
        default: 0,                   //默认值
        displayName: "Score (player)",   //显示名字
        tooltip: "The score of player",   //提示名字

visible: false, //不显示
},
},
ctor: function () { // ctor:表示构造函数
cc.log(“hello===”); //cc.log输出信息,在网页上运行时,按F12,COSONLE面板里会显示; 
},
add: function () { // 自己定义的函数add()
cc.log(“aa===”); //cc.log输出信息,在网页上运行时,按F12,COSONLE面板里会显示; 
}

onLoad () {},                         //导入组件时执行的函数

start () { //开始时执行的函数
this.m_ws= new WebSocket("ws://10.10.30.43:80"); //创建套接字,要用this调用属性,不能直接使用m_ws
this.schedule(function(){ //开启一个定时器,3秒执行一次;
this.m_ws.send("Hello WebSocket, ====="); //发送消息
},3);
},
update (dt) { }, //每桢都执行的函数 
});

2).创建一般的类,保存成文件BB.js:
不继承组件的类,没有onLoad (),start () :等函数,不会自动执行;用来被调用;
var DD= require("DD"); //调用DD.js
var BB=cc.Class({ 
properties: { 
xx:1,
yy:1
}
setDD: function () {
DD.x = 10; //调用DD.js
DD.y=100;
}
});

3).创建模块,保存成文件DD.js:
DD= {
x: null,
y: null,
};
module.exports =DD; //导出模块;有extends: cc.Component,时,不用加这一句,会自动导出; 
//module.exports =new DD(); 

4).静态类
var Sprite = cc.Class({
statics: {
count: 0, // 声明静态变量
//range: { w: 100, h: 100 }
getBounds: function (spriteList) { // 声明静态方法
}
}
});
可以这样写
var Sprite = cc.Class({ ... });
Sprite.count = 0; // 声明静态变量
Sprite.getBounds = function (spriteList) { // 声明静态方法
};

5).导出函数

例1导出函数
// foobar.js:

module.exports.foo = function () { 
cc.log("foo");
};
module.exports.bar = function () {
cc.log("bar");
};

// 调用test.js:
var foobar = require("foobar");
foobar.foo(); // "foo"
foobar.bar(); // "bar"

例2导出属性
// foobar.js:
module.exports = {
FOO: function () {
this.type = "foo";
},
bar: "bar"
};

// test.js:调用
var foobar = require("foobar");
var foo = new foobar.FOO();
cc.log(foo.type); // "foo"
cc.log(foobar.bar); // "bar"

6).两个类相互引用
如果两个类相互引用,脚本加载阶段就会出现循环引用,循环引用将导致脚本加载出错:
///////////Game.js
var Item = require("Item");
var Game = cc.Class({
properties: {
item: {
default: null,
type: Item //用 Item 对象
}
}
});
module.exports = Game;

//////////Item.js
var Game = require("Game");
var Item = cc.Class({
properties: {
game: {
default: null,
type: Game //用 Game 对象
}
}
});
module.exports = Item;

上面两个脚本加载时,由于它们在 require 的过程中形成了闭环,因此加载会出现循环引用的错误,循环引用时 type 就会变为 undefined。
因此我们提倡使用以下的属性定义方式:

/////////Game.js
var Game = cc.Class({
properties: () => ({ //箭头函数在脚本加载中不会同步执行,而是在所有脚本加载成功后才调用。
item: {
default: null,
type: require("Item")
}
})
});
module.exports = Game;

////////Item.js
var Item = cc.Class({
properties: () => ({
game: {
default: null,
type: require("Game")
}
})
});
module.exports = Item;

二,cocos Creator的类:
cc是命名空间;cocos creater引擎下的类得加cc; 如cc.Node cc.v2; 

1).cc.Component组件类
onLoad
start
update
lateUpdate
onDestroy
onEnable
onDisable

2)cc.Node
var node = new cc.Node('dfdf'); //创建
var node = cc.instantiate(this.target); //克隆
this.target.destroy(); //销毁节点并不会立刻被移除,而是在当前帧逻辑更新结束后,统一执行
this.target.removeFromParent(false); //它不一定就能完全从内存中释放

3).组件与子节点:
组件只是添加到节点里的属性;用this.getComponent(cc.Button) 获取
子节点是节点;用this.node.getChildByName(“yy”); 获取
cc.find(“yy”); 任何位置查找节点

4)cc.director 场景切换加载
cc.director.loadScene("MyScene");
cc.director.preloadScene("table", function () {
cc.log("Next scene preloaded");
});

5).cc.loader 加载资源
动态加载资源要注意两点,一是所有需要通过脚本动态加载的资源,都必须放置在 resources 文件夹或它的子文件夹下。resources 需要在 assets 文件夹中手工创建,并且必须位于 assets 的根目录;

Creator 提供了 cc.loader.loadRes 这个 API 来专门加载那些位于 resources 目录下的 Asset。和 cc.loader.load 不同的是,loadRes 一次只能加载单个 Asset。调用时,你只要传入相对 resources 的路径即可,并且路径的结尾处不能包含文件扩展名。

// 加载 Prefab
cc.loader.loadRes("test assets/prefab", function (err, prefab) {
var newNode = cc.instantiate(prefab);
cc.director.getScene().addChild(newNode);
});

// 加载 AnimationClip
var self = this;
cc.loader.loadRes("test assets/anim", function (err, clip) {
self.node.getComponent(cc.Animation).addClip(clip, "anim");
});

// 加载 SpriteAtlas(图集),并且获取其中的一个 SpriteFrame
// 注意 atlas 资源文件(plist)通常会和一个同名的图片文件(png)放在一个目录下, 所以需要在第二个参数指定资源类型
cc.loader.loadRes("test assets/sheep", cc.SpriteAtlas, function (err, atlas) {
var frame = atlas.getSpriteFrame('sheep_down_0');
sprite.spriteFrame = frame;
});

// 加载 SpriteFrame
var self = this;
cc.loader.loadRes("test assets/image", cc.SpriteFrame, function (err, spriteFrame) {
self.node.getComponent(cc.Sprite).spriteFrame = spriteFrame;
});

cc.loader.releaseRes("test assets/image", cc.SpriteFrame);
cc.loader.releaseRes("test assets/anim");

// 加载 test assets 目录下所有资源
cc.loader.loadResDir("test assets", function (err, assets) {
// ...
});

// 加载 sheep.plist 图集中的所有 SpriteFrame
cc.loader.loadResDir("test assets/sheep", cc.SpriteFrame, function (err, assets) {
// assets 是一个 SpriteFrame 数组,已经包含了图集中的所有 SpriteFrame。
// 而 loadRes('test assets/sheep', cc.SpriteAtlas, function (err, atlas) {...}) 获得的则是整个 SpriteAtlas 对象。
});

// 远程 url 带图片后缀名
var remoteUrl = "http://unknown.org/someres.png";
cc.loader.load(remoteUrl, function (err, texture) {
// Use texture to create sprite frame
});

// 远程 url 不带图片后缀名,此时必须指定远程图片文件的类型
remoteUrl = "http://unknown.org/emoji?id=124982374";
cc.loader.load({url: remoteUrl, type: 'png'}, function () {
// Use texture to create sprite frame
});

// 用绝对路径加载设备存储内的资源,比如相册
var absolutePath = "/dara/data/some/path/to/image.png"
cc.loader.load(absolutePath, function () {
// Use texture to create sprite frame
});

6).cc.Event事件
请不要直接创建 cc.Event 对象,因为它是一个抽象类,请创建 cc.Event.EventCustom 对象来进行派发。

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); //删除事件
},
});

当我们从节点 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();
});

Cocos Creator 支持的系统事件包含鼠标、触摸、键盘、重力传感四种;

(1).鼠标事件
// 使用枚举类型来注册
node.on(cc.Node.EventType.MOUSE_DOWN, function (event) {
console.log('Mouse down');
}, this);

// 使用事件名来注册
node.on('mousedown', function (event) {
console.log('Mouse down');
}, this);

枚举对象定义 对应的事件名 事件触发的时机
cc.Node.EventType.MOUSE_DOWN 'mousedown' 当鼠标在目标节点区域按下时触发一次
cc.Node.EventType.MOUSE_ENTER 'mouseenter' 当鼠标移入目标节点区域时,不论是否按下
cc.Node.EventType.MOUSE_MOVE 'mousemove' 当鼠标在目标节点在目标节点区域中移动时,不论是否按下
cc.Node.EventType.MOUSE_LEAVE 'mouseleave' 当鼠标移出目标节点区域时,不论是否按下
cc.Node.EventType.MOUSE_UP 'mouseup' 当鼠标从按下状态松开时触发一次
cc.Node.EventType.MOUSE_WHEEL 'mousewheel' 当鼠标滚轮滚动时
鼠标事件(cc.Event.EventMouse)的重要 API 如下(cc.Event 标准事件 API 之外):
函数名 返回值类型 意义
getScrollY Number 获取滚轮滚动的 Y 轴距离,只有滚动时才有效
getLocation Object 获取鼠标位置对象,对象包含 x 和 y 属性
getLocationX Number 获取鼠标的 X 轴位置
getLocationY Number 获取鼠标的 Y 轴位置
getPreviousLocation Object 获取鼠标事件上次触发时的位置对象,对象包含 x 和 y 属性
getDelta Object 获取鼠标距离上一次事件移动的距离对象,对象包含 x 和 y 属性
getButton Number cc.Event.EventMouse.BUTTON_LEFT 或cc.Event.EventMouse.BUTTON_RIGHT 或cc.Event.EventMouse.BUTTON_MIDDLE

(2).触摸事件
// 使用枚举类型来注册
枚举对象定义 对应的事件名 事件触发的时机
cc.Node.EventType.TOUCH_START 'touchstart' 当手指触点落在目标节点区域内时
cc.Node.EventType.TOUCH_MOVE 'touchmove' 当手指在屏幕上目标节点区域内移动时
cc.Node.EventType.TOUCH_END 'touchend' 当手指在目标节点区域内离开屏幕时
cc.Node.EventType.TOUCH_CANCEL 'touchcancel' 当手指在目标节点区域外离开屏幕时
触摸事件(cc.Event.EventTouch)的重要 API 如下(cc.Event 标准事件 API 之外):
API 名 类型 意义
touch cc.Touch 与当前事件关联的触点对象
getID Number 获取触点的 ID,用于多点触摸的逻辑判断
getLocation Object 获取触点位置对象,对象包含 x 和 y 属性
getLocationX Number 获取触点的 X 轴位置
getLocationY Number 获取触点的 Y 轴位置
getPreviousLocation Object 获取触点上一次触发事件时的位置对象,对象包含 x 和 y 属性
getStartLocation Object 获取触点初始时的位置对象,对象包含 x 和 y 属性
getDelta Object 获取触点距离上一次事件移动的距离对象,对象包含 x 和 y 属性

(3).键盘事件
键盘、设备重力传感器此类全局事件是通过函数 cc.systemEvent.on(type, callback, target) 注册的。
cc.SystemEvent.EventType.KEY_DOWN (键盘按下)
cc.SystemEvent.EventType.KEY_UP (键盘释放)
cc.SystemEvent.EventType.DEVICEMOTION (设备重力传感)

cc.Class({
extends: cc.Component,
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);
},

onKeyDown: function (event) {
    switch(event.keyCode) {
        case cc.KEY.a:
            console.log('Press a key');
            break;
    }
},

onKeyUp: function (event) {
    switch(event.keyCode) {
        case cc.KEY.a:
            console.log('release a key');
            break;
    }
}

});

cc.Class({
extends: cc.Component,
onLoad () {
// open Accelerometer
cc.inputManager.setAccelerometerEnabled(true);
cc.systemEvent.on(cc.SystemEvent.EventType.DEVICEMOTION, this.onDeviceMotionEvent, this);
},

onDestroy () {
    cc.systemEvent.off(cc.SystemEvent.EventType.DEVICEMOTION, this.onDeviceMotionEvent, this);
},

onDeviceMotionEvent (event) {
    cc.log(event.acc.x + "   " + event.acc.y);
},

});

7).动作
cc.ActionInterval 和cc.ActionInstant;

var action = cc.moveTo(2, 100, 100); // 创建一个移动动作
node.runAction(action); // 执行动作
node.stopAction(action); // 停止一个动作
node.stopAllActions(); // 停止所有动作

顺序动作 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);

var seq = cc.repeat( cc.sequence( cc.moveBy(2, 200, 0), cc.moveBy(2, -200, 0) ), 5);
node.runAction(seq);
var seq = cc.repeatForever( cc.sequence( cc.moveBy(2, 200, 0), cc.moveBy(2, -200, 0) ));

var finished = cc.callFunc(this.myMethod, this, opt); //(回调函数,对象,回调方法的传参)

//缓动动作,变成了动作的一个属性;
var aciton = cc.scaleTo(0.5, 2, 2);
action.easing(cc.easeIn(3.0))

容器动作
动作名称 简介
cc.sequence 顺序执行动作
cc.spawn 同步执行动作
cc.repeat 重复执行动作
cc.repeatForever 永远重复动作
cc.speed 修改动作速率
即时动作
动作名称 简介
cc.show 立即显示
cc.hide 立即隐藏
cc.toggleVisibility 显隐状态切换
cc.removeSelf 从父节点移除自身
cc.flipX X轴翻转
cc.flipY Y轴翻转
cc.place 放置在目标位置
cc.callFunc 执行回调函数
cc.targetedAction 用已有动作和一个新的目标节点创建动作
时间间隔动作
动作名称 简介
cc.moveTo 移动到目标位置
cc.moveBy 移动指定的距离
cc.rotateTo 旋转到目标角度
cc.rotateBy 旋转指定的角度
cc.scaleTo 将节点大小缩放到指定的倍数
cc.scaleBy 按指定的倍数缩放节点大小
cc.skewTo 偏斜到目标角度
cc.skewBy 偏斜指定的角度
cc.jumpBy 用跳跃的方式移动指定的距离
cc.jumpTo 用跳跃的方式移动到目标位置
cc.follow 追踪目标节点的位置
cc.bezierTo 按贝赛尔曲线轨迹移动到目标位置
cc.bezierBy 按贝赛尔曲线轨迹移动指定的距离
cc.blink 闪烁(基于透明度)
cc.fadeTo 修改透明度到指定值
cc.fadeIn 渐显
cc.fadeOut 渐隐
cc.tintTo 修改颜色到指定值
cc.tintBy 按照指定的增量修改颜色
cc.delayTime 延迟指定的时间量
cc.reverseTime 反转目标动作的时间轴
cc.cardinalSplineTo 按基数样条曲线轨迹移动到目标位置
cc.cardinalSplineBy 按基数样条曲线轨迹移动指定的距离
cc.catmullRomTo 按 Catmull Rom 样条曲线轨迹移动到目标位置
cc.catmullRomBy 按 Catmull Rom 样条曲线轨迹移动指定的距离

8).定时器
component.schedule( function() { this.doSomething(); }, 5); //(函数,间隔)
component.schedule(function() {
this.doSomething();
}, 1, 5, 3); //(函数,间隔,重复次数,开始延时)
component.scheduleOnce(function() { this.doSomething(); }, 2);
this.unschedule(this.callback);
this.unscheduleAllCallbacks();//取消这个组件的所有计时器

9).对象池cc.NodePool
把层级管理器中的节点拖进资源管理器中就创建了预制体;
let和var 一样,是声明变量的关键词, 同一个变量名时,var 即使在{}内也作用全局,let有范围;
(1)将需要数量的节点创建出来,并放进对象池:
//...
properties: {
enemyPrefab: cc.Prefab
},
onLoad: function () {
this.enemyPool = new cc.NodePool();
let initCount = 5;
for (let i = 0; i < initCount; ++i) {
let enemy = cc.instantiate(this.enemyPrefab); // 创建节点
this.enemyPool.put(enemy); // 通过 putInPool 接口放入对象池
}
}

(2)获得对象池中储存的对象了:
// ...
createEnemy: function (parentNode) {
let enemy = null;
if (this.enemyPool.size() > 0) { // 通过 size 接口判断对象池中是否有空闲的对象
enemy = this.enemyPool.get();

else { // 如果没有空闲对象,就用 cc.instantiate 重新创建
enemy = cc.instantiate(this.enemyPrefab);
}
enemy.parent = parentNode; // 将生成的敌人加入节点树
enemy.getComponent('Enemy').init(); //接下来就可以调用 enemy 身上的脚本进行初始化
}

(3)节点退还给对象池,以备之后继续循环利用,:
// ...
onEnemyKilled: function (enemy) {
this.enemyPool.put(enemy); // 将节点放进对象池,这个方法会同时调用节点的 removeFromParent();
}

myPool.clear(); // 调用这个方法就可以清空对象池

10).Button添加事件

Button 目前只支持 Click 事件,即当用户点击并释放 Button 时才会触发相应的回调函数。
通过脚本代码添加回调
方法一
这种方法添加的事件回调和使用编辑器添加的事件回调是一样的,通过代码添加, 你需要首先构造一个 cc.Component.EventHandler 对象,然后设置好对应的 target, component, handler 和 customEventData 参数。
//here is your component file, file name = MyComponent.js 
cc.Class({
extends: cc.Component,
properties: {},

onLoad: function () {
    var clickEventHandler = new cc.Component.EventHandler();
    clickEventHandler.target = this.node; //这个 node 节点是你的事件处理代码组件所属的节点
    clickEventHandler.component = "MyComponent";//这个是代码文件名
    clickEventHandler.handler = "callback";
    clickEventHandler.customEventData = "foobar";

    var button = node.getComponent(cc.Button);
    button.clickEvents.push(clickEventHandler);
},

callback: function (event, customEventData) {
    //这里 event 是一个 Touch Event 对象,你可以通过 event.target 取到事件的发送节点
    var node = event.target;
    var button = node.getComponent(cc.Button);
    //这里的 customEventData 参数就等于你之前设置的 "foobar"
}

});

方法二
通过 button.node.on('click', ...) 的方式来添加,这是一种非常简便的方式,但是该方式有一定的局限性,在事件回调里面无法 获得当前点击按钮的屏幕坐标点。
//假设我们在一个组件的 onLoad 方法里面添加事件处理回调,在 callback 函数中进行事件处理:
cc.Class({
extends: cc.Component,
properties: {
button: cc.Button
},

onLoad: function () {
   this.button.node.on('click', this.callback, this);
},

callback: function (event) {
   //这里的 event 是一个 EventCustom 对象,你可以通过 event.detail 获取 Button 组件
   var button = event.detail;
   //do whatever you want with button
   //另外,注意这种方式注册的事件,也无法传递 customEventData
}

});

11).EditBox添加事件
方法一
这种方法添加的事件回调和使用编辑器添加的事件回调是一样的,通过代码添加, 你需要首先构造一个 cc.Component.EventHandler 对象,然后设置好对应的 target, component, handler 和 customEventData 参数。

var editboxEventHandler = new cc.Component.EventHandler();
editboxEventHandler.target = this.node; //这个 node 节点是你的事件处理代码组件所属的节点
editboxEventHandler.component = "cc.MyComponent"
editboxEventHandler.handler = "onEditDidBegan";
editboxEventHandler.customEventData = "foobar";

editbox.editingDidBegan.push(editboxEventHandler);
// 你也可以通过类似的方式来注册其它回调函数
//editbox.editingDidEnded.push(editboxEventHandler);
//editbox.textChanged.push(editboxEventHandler);
//editbox.editingReturn.push(editboxEventHandler);

//here is your component file
cc.Class({
name: 'cc.MyComponent'
extends: cc.Component,

properties: {   },

onEditDidBegan: function(editbox, customEventData) {
    //这里 editbox 是一个 cc.EditBox 对象
    //这里的 customEventData 参数就等于你之前设置的 "foobar"
},
//假设这个回调是给 editingDidEnded 事件的
onEditDidEnded: function(editbox, customEventData) {
    //这里 editbox 是一个 cc.EditBox 对象
    //这里的 customEventData 参数就等于你之前设置的 "foobar"
}
//假设这个回调是给 textChanged 事件的
onTextChanged: function(text, editbox, customEventData) {
    //这里的 text 表示 修改完后的 EditBox 的文本内容
    //这里 editbox 是一个 cc.EditBox 对象
    //这里的 customEventData 参数就等于你之前设置的 "foobar"
}
//假设这个回调是给 editingReturn 事件的
onEditingReturn: function(editbox,  customEventData) {
    //这里 editbox 是一个 cc.EditBox 对象
    //这里的 customEventData 参数就等于你之前设置的 "foobar"
}

});

方法二
通过 editbox.node.on('editing-did-began', ...) 的方式来添加
//假设我们在一个组件的 onLoad 方法里面添加事件处理回调,在 callback 函数中进行事件处理:

cc.Class({
extends: cc.Component,
properties: {
editbox: cc.EditBox
},

onLoad: function () {
   this.editbox.node.on('editbox', this.callback, this);
},

callback: function (event) {
   //这里的 event 是一个 EventCustom 对象,你可以通过 event.detail 获取 EditBox 组件
   var editbox = event.detail;
   //do whatever you want with the editbox
}

});

12).scrollview添加事件

方法一
这种方法添加的事件回调和使用编辑器添加的事件回调是一样的,通过代码添加, 你需要首先构造一个 cc.Component.EventHandler 对象,然后设置好对应的 target, component, handler 和 customEventData 参数。
//here is your component file, file name = MyComponent.js 
cc.Class({
extends: cc.Component,
properties: {},

onLoad: function () {
    var scrollViewEventHandler = new cc.Component.EventHandler();
    scrollViewEventHandler.target = this.node; //这个 node 节点是你的事件处理代码组件所属的节点
    scrollViewEventHandler.component = "MyComponent";//这个是代码文件名
    scrollViewEventHandler.handler = "callback";
    scrollViewEventHandler.customEventData = "foobar";

    var scrollview = node.getComponent(cc.ScrollView);
    scrollview.scrollEvents.push(scrollViewEventHandler);
},

//注意参数的顺序和类型是固定的
callback: function (scrollview, eventType, customEventData) {
    //这里 scrollview 是一个 Scrollview 组件对象实例
    //这里的 eventType === cc.ScrollView.EventType enum 里面的值
    //这里的 customEventData 参数就等于你之前设置的 "foobar"
}

});

方法二
通过 scrollview.node.on('scroll-to-top', ...) 的方式来添加
//假设我们在一个组件的 onLoad 方法里面添加事件处理回调,在 callback 函数中进行事件处理:
cc.Class({
extends: cc.Component,
properties: {
scrollview: cc.ScrollView
},

onLoad: function () {
   this.scrollview.node.on('scroll-to-top', this.callback, this);
},

callback: function (event) {
   //这里的 event 是一个 EventCustom 对象,你可以通过 event.detail 获取 ScrollView 组件
   var scrollview = event.detail;
   //do whatever you want with scrollview
   //另外,注意这种方式注册的事件,也无法传递 customEventData
}

});

三 数据存储:
1.数据库存储
使用 cc.sys.localStorage 接口来进行用户数据存储和读取的操作。
存储在 sqlite数据库。

cc.sys.localStorage.setItem(key, value); //键值 key,字符串数据 value。
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)
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));
确保游戏存档不被破解,请使用服务器进行数据存取。

2.全局变量
刚学习Cocos Creator 开发游戏 需要跨场景传递数据 通过浏览官方文档终于解决了
1).使用常驻节点
cc.game.addPersistRootNode(myNode); //myNode设置成常驻节点,与canvers画布平级,场景切换时不会清除这个节点;cc.game.removePersistRootNode(myNode)//将取消这个节点的常驻属性

(1)新建一个空节点datanode,放在画布外,
(2)新建一个脚本gdata.js;添加到节点;
px:10,
onLoad () {
cc.game.addPersistRootNode(this.node); //把所在的节点设置成常驻节点 
},
(3)新建一个脚本bb.js;添加到场景1的节点上;
var nod=cc.find("datanode"); //查找节点
var px=nod.getComponent("gdata").px; //获取节点的脚本组件
cc.log(px); //输出10
nod.getComponent("gdata").px=1000; //修改值
(4)脚本bb.js;添加到场景2的节点上;
var nod=cc.find("datanode"); //查找节点
var px=nod.getComponent("gdata").px; //获取节点的脚本组件
cc.log(px); //输出1000

2). 使用全局变量
window.Global = {
.........
};
这样你就可以随时访问Global了 (全局变量不要和系统的全局变量重名 ,要初始化)

3).通过模块访问
(1)写成模块
在DataMng.js中写如下代码
module.exports = {
nn:”hghgh”,
mm:100,
}; 
//调用
var obj= require("DataMng"); //调用DataMng.js
obj.nn=”ddsdsdsds”; //可以被多个类修改

(2)写成类
DD.js写在类里面就不能修改:
module.exports =cc.Class({
properties: {
px:"10", //没用
py:20,
},

ctor: function () {  
    this.px=100;    //没用
    this.py=200;
},

});
//调用
var DD= require("DD"); //调用DataMng.js
cc.log(DD.px); //将提示没定义;没有构造DD的对象
var obj2=new DD();
cc.log(obj2.px); //可以显示100

obj.px=”ddsdsdsds”; //可以被多个类修改

(3)DataMng.js写成模块,包含类对象
var DD= require("DD"); //调用DD.js
module.exports = {
nn: "kkHH",
dd:{
default:new DD(), //构造DD的对象
type:DD,
},
};

//调用
var obj= require("DataMng"); //调用DataMng.js
cc.log(obj.bb.px); //可以显示100

3.json文件的读写

//load()方法,数据文件必须放到resources下
cc.loader.load(cc.url.raw('resources/data.json'), function(err,res){
if (err) { cc.log(err); }
else{
let list=res;
cc.log("load:");
cc.log("list:"+list.name);
}
}); 

//louadRes()方法,默认路径就是resources
cc.loader.loadRes('data', function(err,res){
if (err) { cc.log(err); }
else{
let list=res;
cc.log("loadRes:");
cc.log("list:"+list.sex);
}
});

写入xml
if(cc.sys.isNative) {
cc.log("Path:"+jsb.fileUtils.getWritablePath());
cc.log( jsb.fileUtils.writeToFile({"new":"value"},jsb.fileUtils.getWritablePath()+'data.json'));
cc.log("fullPathForFilename:"+jsb.fileUtils.fullPathForFilename("resources/data.json"));

//
jsb.fileUtils.writeStringToFile('{"a":"b","c":"d"}', jsb.fileUtils.getWritablePath()+'kk.json');
JSON.stringify(jsb.fileUtils.getValueMapFromFile(jsb.fileUtils.getWritablePath()+"kk.json")); 

         第三章  发布

1.发布成网页
进度条后有个按钮可以打开编译日志;
项目----构建发布----发布平台----web desktop web mobile;
先点构建----进度条完了,再点运行;
到TY\build\web-desktop里打开index.html是运行不了的,
用IE打开构建面板上的预览URL也可以运行;

构建出错的日志在:C:\Users\qbkf.CocosCreator\logs\native.log 

2.发布成微信小程序
(1)
下载安装微信的微信web开发者工具软件:
https://mp.weixin.qq.com/debug/wxagame/dev/devtools/download.html?t=20181156

(2)
cocos creator----偏好设置----原生开发环境----wechatgame,设置上面软件安装的目录;
项目----构建发布----发布平台----wechatgame; 
先点构建----进度条完了,再点运行;

(3)
打开微信web开发者工具----右下角的+号----
项目目录为D:\cocos\TY\build\wechatgame(cocos creator构建的目录);
appid:如果没有可以点体验小程序;
打开项目后,点编译,
点预览显示二维码--用手机上的微信扫描一下就能在手机上玩了;

3.发布成apk
安装好jdk,sdk,ndk,ant等android发布环境后;

项目----构建发布----发布平台----android; 
不用android studio 配置环境的要去掉android studio 项,不然提示找不到ndk;
版本问题的看日志升级工具和ndk库;
apk文件在:D:\cocos\TT\build\jsb-link\simulator\android

4.发布成windows
项目----构建发布----发布平台----windows; 
在安装 Visual Studio 时(最低版本2013),默认并没有勾选 C++ 编译组件。
如果没有安装,则需要重新安装并选择 C++ 相关编译组件。

猜你喜欢

转载自blog.csdn.net/xuefujin/article/details/80395983
今日推荐