+assets (项目资源的根目录名)
-Texture (存放其他资源)
-Script (存放脚本文件) ccc中脚本名就是组件名,大小写敏感!
-Scene (存放游戏场景)
cc.Class({
extends: cc.Component,
properties: {
label: {
default: null,
type: cc.Label
},
// defaults, set visually when attaching this script to the Canvas
text: 'Hello, World!'
},
// 用于初始化
onLoad: function () {
this.label.string = this.text;
},
// called every frame
update: function (dt) {
},
});
properties :组件(挂载到场景中的节点上,提供控制节点的各种功能;这些properties可以直接在属性检查器中设置)
onload :页面一加载完就执行里面的函数代码
update : 根据时间实时更新,更新回调
需要重复生成的节点,我们可以将他保存成Prefab(预制)资源,作为我们动态生成节点时使用的模板
比如将Texture文件夹下的一张图片,拖到层级管理器系统即是场景的canvas里面,再从层级管理器拖到Texture文件夹中就是预制资源(预制资源的图标是个灰色正方形)啦(我也觉得这操作有点奇怪)
cc.moveBy("几秒",cc.p("横坐标","纵坐标")) 移动指定的距离
cc.moveTo("几秒",cc.p("横坐标","纵坐标")) 移动到目标位置
cc.easeCubicActionOut() 创建 easeCubicActionOut 缓动对象 ,就是缓慢减速的一种效果
cc.repeatForever("一个序列") 永远地重复一个动作
node.runAction("动作序列名") 执行并返回该执行的动作。该节点将会变成动作的目标。
this.node.addChild("节点名","层级数字"); 添加子节点
"节点名".setPosition(); 设置节点在父节点坐标系中的位置
cc.callFunc 执行回调函数
"节点名".removeFromParent 从父节点中删除该节点
cc.sequence(); 顺序执行动作,创建的动作将按顺序依次运行
Scene 每个游戏都会用到场景切换!
Director类 游戏导航仪,控制 初始化,场景切换,游戏暂停继续等等
cc.director.loadScene("场景名"); 加载一个场景
cc.director.preloadScene("场景名"); 预加载场景(比如图片资源比较大就可以用它预先加载)
this.node.on("事件名","函数"); 事件(事件名,function)
this.schedule(function(){},1); 类似js的setTimeout
改变一个标签上面的文字居然是这样的 this.timeLabel.string=4; (说好的和js差不多呢)
模拟手机游戏的场景的canvas要改成 W:640 H: 960
EventTarget 事件目标是事件触发时,分派的事件对象,Node 是最常见的事件目标, 但是其他对象也可以是事件目标
8. 关闭左下角的fps面板,在场景脚本的文件中 onLoad 的函数中写以下:
cc.director.setDisplayStats(false);
=======================================================
腾讯课堂-cocos creator/cocos 2dx 入门 听课笔记
1. 使用ts来做ccc开发新建的脚本文件是这样的: (代码实现一只扇翅膀的小鸟)
const {ccclass, property} = cc._decorator;
@ccclass
export default class NewClass extends cc.Component {
@property(cc.Label)
label: cc.Label = null;
@property(cc.Sprite)
bird0: cc.Sprite = null;
@property(cc.Sprite)
bird1: cc.Sprite = null;
@property(cc.Sprite)
bird2: cc.Sprite = null;
@property(cc.Sprite)
bird3: cc.Sprite = null;
@property(cc.Node)
birdParent: cc.Node = null;
@property
text: string = 'hello';
time: number = 0; // 距离上次切换显示的小鸟 流失的时间
// LIFE-CYCLE CALLBACKS:
// onLoad () {}
start () {
}
update (dt: number) {
// console.log(dt);
let timeTmp = this.time + dt;
this.time = timeTmp;
if(this.time > 0.5){
if(this.bird0.node.active){
this.bird0.node.active = false;
this.bird1.node.active = true;
}else if (this.bird1.node.active){
this.bird1.node.active = false;
this.bird2.node.active = true;
}else if (this.bird2.node.active){
this.bird2.node.active = false;
this.bird3.node.active = true;
}else if (this.bird3.node.active){
this.bird3.node.active = false;
this.bird0.node.active = true;
}
this.time = 0;
}
let birdY = this.birdParent.y;
this.birdParent.y = birdY - 1;
}
}
// 重点来了,自定义枚举
/**
* 全局变量
* const LEVEL = cc.Enum({EASY:1,HARD:2});
*/
@property({
type:LEVEL
})
enumVa = LEVEL.EASY;
2. 帧的概念是这样的: 比如一秒60帧,说明一秒钟画面刷新了60次,帧数为 1/60
3. 节点 Node 是包含 组件的
4. 代码执行遇到return整个函数就都不执行了
5. BMfont 可以用图片数字来代替真实数字(不知道怎么做的)
=============================================================
1. ccc是一个组件化的开发工具
2. Prefab: 预制体,预制资源
// 预(提前)制体
@property(cc.Prefab)//预制体类型
myPrefab:cc.Prefab=null;//需要被克隆的对象
//程序运行后加载对象
start(){
var loadobj =cc.instantiate(this.myPrefab);//将预制体克隆到场景
this.node.addChild(loadobj);//将克隆出的物体作为子物体
//设置物体位置
loadobj.setPosition(cc.p(300,-150));
//5秒之后销毁对象
setTimeout(
function(){ //匿名方法
loadobj.destroy();
}
,5000);
}
3. ccc 的生命周期函数:
- onLoad(会在这个组件所在的场景被载入的时候触发,执行最早的方法 只执行一次,在场景加载后立刻执行)
- start(会在组件第一次激活前,也就是第一次执行 update 之前触发,start 在onload 之后执行只执行一次)
- update(游戏开发一个关键是在每一帧渲染前更新物体的行为,状态和方位。这些更新操作通常都放在 update 回调中,会在所有动画更新前执行)(update 可以不带参数 参数的意思是游戏一帧执行的时间 大概为0.017秒 数值不固定)
- lateUpdate(动画更新后进行额外操作,在update执行之后马上执行 ,需要用到 lateUpdate 回调)
- onDestroy(当组件调用了 destroy(),会在该帧结束被统一回收,此时会调用 onDestroy 回调。执行最晚的方法,物体被销毁之前执行)
- onEnable(当组件的 enabled 属性从 false 变为 true 时,会激活 onEnable 回调。倘若节点第一次被 创建且 enabled
为 true,则会在 onLoad 之后,start 之前被调用。脚本启用会执行)- onDisable(当组件的 enabled 属性从 true 变为 false 时,会激活 onDisable 回调,脚本禁用会执行)
4. Cocos Creator 中脚本名称就是组件的名称,这个命名是大小写敏感的!如果组件名称的大小写不正确,将无法正确通过名称使用组件!
5. 通过学习官网demo摘星星总结开发流程:
properties: {
}
=================================================
1. 在场景的canvas的属性检查器中找到Group点击编辑可以分组配置碰撞检测
2. 添加物理边缘步骤(点击节点-添加组件-物理-collider-Box)如果边界是静止的吗,要在Rigidbody--type--static
3. 什么是ccc组件化开发: 节点 + 组件1 + 组件2 + 组件3 。。。 (也就是一个节点带着不同功能的组件)(开发一个功能,都是从组件开始的)
a: 创建一个组件类
b: new 组件类出来
c: 管理这些组件实例
(1): 运行场景的时候初始化:
遍历场景里面的每个节点,
遍历节点上面的每个组件实例;
调用 组件实例.onLoad, --> 组件实例在加载的时候调用;
调用 组件实例.start -->组件实例在开始运行之前调用一次;
(2): 每次游戏刷新的时候
4. 在一个节点操作 添加我们自己定义的脚本组件原来就是 实例化一个类
5. 开启物理引擎:
cc.director.getPhysicsManager().enabled = true;
开启调试状态/模式(给指定物理系统需要绘制哪些调试信息):
var draw = cc.PhysicsManager.DrawBits;
cc.director.getPhysicsManager().debugDrawFlags = draw.e_shapeBit|draw.e_jointBit;
物理引擎的脚本要挂载到根节点上,然后一定要在该脚本的onload()方法中所有的动作初始化前开启物理引擎。
6. 弧度转角度: 角度值 = 弧度值*180 / Math.PI
7. 碰撞检测:
- onBeginContact: 碰撞开始被调用
- onEndContact: 碰撞结束被调用
- onPreSolve: 碰撞接触更新前调用
- onPostSolve: 碰撞接触更新后调用
- 参数:contact 碰撞信息 ,selfCollider 自己的碰撞器 , otherCollider 撞到的谁
8. 微信打包发布:
- 发布微信的话 canvas 节点上只能选择 Fit Width ,Fit Height 不能选
- 项目--构建发布--发布平台(Wechat Game),MD5 Cache 选上,设备方向(竖屏选Portrait,横屏选landscape),appid(自己填自己的)--构建--运行(就会打开微信开发工具)--预览--扫描二维码玩游戏
- cocos creator--偏好设置--原生开发环境--wechatGame程...(选择微信开发工具的地址exe的位置)
===============================================
1. moveBy:移动指定的距离
var jumpUp = cc.moveBy(this.jumpTimes,cc.p(0,this.jumpHeight));
2. cc.sequence: 顺序执行动作,创建的动作将按顺序依次运行
var seq = cc.sequence(this.jumpAction,this.maxMoveSpeed);
3. runAction: 执行并返回该执行的动作。该节点将会变成动作的目标。
this.node.runAction(seq);
4. getComponent: 获取节点上指定类型的组件,如果节点有附加指定类型的组件,则返回,如果没有则为空。
传入参数也可以是脚本的名称。
var HeroPlayer = require("HeroPlayer");
...
var hero = self.player.getComponent(HeroPlayer);
5. 除了微信小游戏以外,其他类型的小游戏 Canvas 中的Fit Height与Fit Width 一定要勾选上(为了适配)
6. cc.winSize: 为当前的游戏窗口的大小。
7. 获取一张图片的宽度:
this._width = this.groundImg.spriteFrame.getRect().width;
8. 定时器:参数是回调函数和时间
this.schedule(function(),this.move_time)
9. 写动画(帧动画,例如 像素鸟的小鸟不断煽动翅膀)
动画编辑器--添加animation组件--新建animationClip(存储在anim文件夹里面)--点击动画编辑器的左上角编辑按钮--属性列表点击 add property---选择 cc.Sprite.spriteFrame--点 “+” 号 -- 拉一帧点一次 “+” 号 -- 替换帧对应的图片--wrapMode选择Loop--点击左上角的播放按钮--保存--关闭--新建脚本--脚本拉到属性检查器--动画文件拉到对应位置--playOnload打钩--预览
10. 获取节点上指定类型的组件,如果节点有附加指定类型的组件,则返回,如果没有则为空。传入参数也可以是脚本的名称:
var pipeUp = cc.instantiate(this.pipePrefabs[0]);
pipe.getComponent('Pipe').init(0);
11. 返回父节坐标系下的轴向对齐的包围盒:(包围后是以盒的左下角为中心的)
var boundingBox = node.getBoundingBox();
12. 获取与设置本地 localstorage 的值:
cc.sys.localStorage.getItem('name');
cc.sys.localStorage.setItem('name',score);
13. 动画效果(例如为得分文字添加小动画):
var action1 = cc.scaleTo(this.scoreTime,1.1,0.6);
var action2 = cc.scaleTo(this.scoreTime,0.8,1.2);
var action3 = cc.scaleTo(this.scoreTime,1,1);
//播放形变动画
this.curScoreText.node.runAction(cc.sequence(action1,action2,action3));
========================================
1. 任何一个节点都会有一个 cc.Node(cc.Node是场景树中的节点对象);
2. cc.Node.rotation: 旋转,顺时针为正,数学逆时针为正;
3. cc.Node.anchor: 锚点,左下角(0,0),右上角(1,1),可以超过这个范围;
4. 在代码组件里面,使用 this.node 访问这个组件实例挂载的节点对象;
5. cc.Node.children/childrenCount: 获得孩子节点数组、孩子节点数量;
6. cc.Node场景树相关方法:
new cc.Node():代码中创建一个节点
setPosition/getPosition: 获取或设置节点的相对位置
cc.find(): 方便,不通用, 消耗
7. 触摸事件的类型:START, MOVED, ENDED(物体内弹起), CANCEL(物体外弹起);
8. 监听触摸事件: node.on(类型, callback, target(回掉函数的this), [useCapture]);
9. 关闭触摸事件: node.off(类型, callback, target(回掉函数的this), [useCapture]);
4. targetOff(target):移除所有的注册事件;
5. 触摸事件中回调函数的参数t:t.getLocation() 获取当前触点位置 ; t.getDelta() 获取触点距离上一次事件移动的距离对象,对象包含 x 和 y 属性(也就是距离上一次触摸变化了多少)
//在触摸移动的事件类型中的回调函数
var delta = t.getDelta();
this.node.x += delta.x;
this.node.y += delta.y;
//以上代码实现节点物体随着你点击移动的位置移动
6. stopPropagationImmediate: 立即停止当前事件的传递,事件甚至不会被分派到所连接的当前目标;
7. 监听键盘事件:cc.SystemEvent.on(type, function, target, useCapture);监听的时候,我们需要一个cc.SystemEvent类的实例,我们有一个全局的实例cc.systemEvent,小写开头(实际使用时小写开头的)
8. 自定义事件:
start: function() {
// 派发者,只能传递给自己,不会向上传递
this.node.emit("pkg_event", {blake: "huang"});
// end
// 派送者,不只是发给自己,发给我们这个体系;
// true/false, true向上传递, false不向向上传递
var e = new cc.Event.EventCustom("pkg_event", true);
e.detail = {blake: "huang"};
this.node.dispatchEvent(e);
},
9. ccc坐标系:
相对(节点)坐标系,两种相对节点原点的方式(1) 左下角为原点, (2) 锚点为原点(AR)
节点坐标和屏幕坐标的相互转换; 我们到底使用哪个?通常情况下带AR;
// 节点坐标转到屏幕(世界)坐标 cc.p(0, 0)
var w_pos = this.node.convertToWorldSpace(cc.p(0, 0)); // 左下角为原点的 cc.p(430, 270)
console.log(w_pos);
w_pos = this.node.convertToWorldSpaceAR(cc.p(0, 0)); // 锚点为原点 cc.p(480, 320)
console.log(w_pos);
// end
var w_pos = cc.p(480, 320);
var node_pos = this.node.convertToNodeSpace(w_pos);
console.log(node_pos); // cc.p(50, 50)
node_pos = this.node.convertToNodeSpaceAR(w_pos);
console.log(node_pos); // cc.p(0, 0)
// 获取节点的包围盒, 相对于父亲节点坐标系下的包围盒
var box = this.node.getBoundingBox();
console.log(box);
// 世界坐标系下的包围盒
var w_box = this.node.getBoundingBoxToWorld();
console.log(w_box);
this.node.on(cc.Node.EventType.TOUCH_START, function(t) {
var w_pos = t.getLocation();
var pos = this.node.convertToNodeSpaceAR(w_pos);
console.log(pos);
pos = this.node.convertTouchToNodeSpaceAR(t);
console.log("====", pos);
}, this);
// 我要把当前这个sub移动到世界坐标为 900, 600;
//
// 把世界坐标转到相对于它的父亲节点的坐标
var node_pos = this.node.parent.convertToNodeSpaceAR(cc.p(900, 600));
this.node.setPosition(node_pos); // 相对于this.node.parent这个为参照物,AR为原点的坐标系
// end
// 获取当前节点的世界坐标;
this.node.convertToWorldSpaceAR(cc.p(0, 0));
10. Action的使用:
MoveTo:(x, y) → (x1, y1)
MoveBy:(x, y) → (x + x1, y + y1)
cc.sequnce, cc.repeat, cc.repeatForever
Action easing(缓动的方式): 加上缓动特效, cc.easeXXXXX查看文档设置自己想要的缓动对象
stopAction: 停止运行action
stopAllActions: 停止所有的action;
onLoad: function () {
// move
// var mto = cc.moveTo(1, cc.p(100, 100)); // cc.moveTo(1, x, y);
// this.node.runAction(mto);
// var mby = cc.moveBy(1, cc.p(100, 100)); // cc.moveBy(1, x, y); 变化多少
// this.node.runAction(mby);
// rotate
// var rto = cc.rotateTo(1, 180); // 旋转到180度; rotation 180;
// this.node.runAction(rto);
// var rby = cc.rotateBy(1, 75); // 在原来的基础上,变化75,可正,可负
// this.node.runAction(rby);
// scale
// this.node.scale = 2;
// var sto = cc.scaleTo(1, 1.1); // 到1.1倍
// this.node.runAction(sto);
// this.node.scale = 2;
// var sby = cc.scaleBy(1, 1.1); // 原来的基础,变化1.1 * 2
// this.node.runAction(sby);
// opactify
// var fin = cc.fadeIn(1);
// this.node.opacity = 0;
// this.node.runAction(fin);
// var fout = cc.fadeOut(1);
// this.node.runAction(fout); // 物体还是在的的
// var fto = cc.fadeTo(1, 128);
// this.node.runAction(fto);
// function Action
/*var func = cc.callFunc(function() {
console.log("call Func actin!!!!!");
}.bind(this));
console.log("begin ####");
this.node.runAction(func);
console.log("end ####");*/
// 移动到 目的地,后,隐藏这个物体怎办? // 命令清单, [Action1, A2, A3],
// seq Action
/*var m1 = cc.moveTo(1, 100, 100);
var fout = cc.fadeOut(0.5);
var seq = cc.sequence([m1, fout]);
this.node.runAction(seq);*/
// 一个节点可以同时运行多个Action, 一边,一边
/*var m1 = cc.moveTo(1, 100, 100);
var fout = cc.fadeOut(0.5);
this.node.runAction(fout);
this.node.runAction(m1);*/
// 不断的放大缩小
/*var s1 = cc.scaleTo(0.8, 1.1);
var s2 = cc.scaleTo(0.8, 0.8);
var seq = cc.sequence([s1, s2]);
var rf = cc.repeatForever(seq);
this.node.runAction(rf);*/
// 匀速的飞过,傻了, 缓动
// 回弹
/*this.node.y = 0;
var m = cc.moveTo(1, 100, 0).easing(cc.easeBackOut());
this.node.runAction(m);*/
/*var r = cc.rotateBy(3, 360).easing(cc.easeCubicActionOut());
var rf = cc.repeatForever(r);
this.node.runAction(rf);
// this.node.stopAction(rf);
this.node.stopAllActions();*/
// end
// 移动了到100, 0,删除
/*var m = cc.moveTo(1, 100, 0);
var end_func = cc.callFunc(function() {
this.node.removeFromParent();
}.bind(this));
var seq = cc.sequence([m, end_func]);
this.node.runAction(seq);*/
// cc.Delay,
var d1 = cc.delayTime(3);
var fout = cc.fadeOut(0.5);
var end_func = cc.callFunc(function() {
this.node.removeFromParent();
}.bind(this))
var seq = cc.sequence([d1, fout, end_func]);
this.node.runAction(seq);
},
11. cc.Component属性(组件类,所有组件的基类)
var my_item = require("my_item");
...
properties: {
//基本数据类型,数,bool,字符串,color,pos,size
speed: 100,
is_debug: false,
url_str: "",
color: cc.color(0,0,0,255),
pos: cc.p(0,0),
size: cc.Size(100,100)
// 系统的组件
sprite_item: {
type: cc.Sprite,
default: null, // null/[]
}
// 组件的代码组件
custom_comp: {
type: my_item,
default: null, // null/[]
},
}
12. cc.Sprite: 配置图片的SIZE_MODE
CUSTOM 大小和CCNode的大小一致;
RAW 原始的图片大小;
TRIMMED 大小为原始图片大小, 显示的内容是裁剪掉透明像素后的图片;
trim: 是否裁剪掉 图片的透明区域, 如果勾选,就会把完全透明的行和列裁掉, 做帧动画的时候,我们一般是用原始大小不去透明 度,动画,不至于抖动;
13. Filled模式(游戏中道具的时间进度显示条、个性化时间进度条案例等应用,比较常用,最好掌握)
Fill Start 开始的位置: 0 ~1, 右边中心点开始,逆时针走
Fill Range: 填充总量(0, 1];
FillRange为正,那么就是逆时针,如果为负,那么就是顺时针;