TS入门
记录常用的
系统学习可参考:菜鸟教程
1、语法规范:
以换行分割语句,
可省略末尾分号,同一行需要使用分号来分隔
2.打印log
console.log("Hello World!")//白色,一般提示 console.warn("Hello World!")//黄色,警告 console.error("Hello World!")//红色,报错
3、注释
//单行注释 /** * 多行注释 * */
4、对象object,类class,方法function
面向对象和面向过程
ts文件基本包含
//className类名 class className { //方法,函数 main() { //调用函数 this.functionA() } functionA() { //变量 let a = 1; console.log(a); } }
5、基础类型
any 任意类型
number 数字,包含小数,整数
string 字符串
boolean,
array,
enum
void.
object 对象{a:1}
数组,对象,字符串详解
6、创建变量,方法,类
变量命名规范
const
//const 创建常数,创建以后不可改变 //也可以用来创建object,可改变里面内容 const b = 1; const obj = { a: 1, b: 2 } obj.a = 2; //输出 obj "obj = { a: 2, b: 2 }" obj = null; //输出 obj,失败,会报错
let
//类型为小数,整数,二进制等用number let a2_1: number = 1.1; let a2_2: number = 1; //类型为字符串用string let a3_1: string = "a"; let a3_2: string = 'a'; let a3_3: string = `a`;//推荐这种写法 let a3_4: string = `a${a2_1}`;//可和表达式混写,结果为 `a1.1` //类型为true,false用boolean let a4_1: boolean = true; //定义数组 let a5_1: number[] = [1, 2, 3] //定义对象,自定义类型 type test_obj = { name: string, id: number } let a6_1: test_obj = null let a6_2: test_obj = { name: "aaa", id: 666 } //以上所有类型都可以用any,写any则编辑器不校验类型,为了规范不建议用 let a7_1: any = 1; a7_1 = "";//类型为any不报错 //不写类型会按第一个赋值的内容推断类型 let a8_1 = 1; a8_1 = "";//类型推断number,编辑器会报错 //类和函数 class classNameTest { //无返回值用void functionA(): void { } //返回number类型,可用类型同上方 functionB(): number { return 1 } } //含有多种类型 let a9_1: number | string = 1 a9_1 = "aaa"//不会报错 //问号以及默认值使用 function functionC(a: string, b?) { } function functionD(a: string, b = 1) { } functionC("111")//类型后标记问号,可不传 functionC("111")//类型后有默认值,可不传
7、运算符+,-,*,/,%,++,–,+=,-=,!,||,&&
+,-,*,/,%
加 减 乘 除
%求余
5%2=1 结果为5除以2的余数
++,–,+=,-=
自增,自减
a++ 等于 a=a+1
// a++和++1 a=1;b=a++ b=a;a++ b=1;a=2 a=1;b=++a a=a+1;b=a a=2;b=2; a+=1 a=a+1,也可以简写成a++
! 非,&&且 ||或
&& 运算符只有在左右两个表达式都为 true 时才返回 true。
|| 运算符只要其中一个表达式为 true ,则返回 true。
//!表示非,返回true,false let a4_2: boolean = !1;//返回false let a4_3: boolean = !!1;//返回true
8、条件语句
if…else
if(A){ } else if(B){ } else{ } //只有if判断可省略{} if(a==1)a=2;
判断字段为空
//判断字段不为空 if(a){ funA() }else{ funB() } a为0,"",null,undefined会走funB a为[],{},NAN会走funA //cocos creator里,判断字段不为undefined,null可用 if (cc.isValid(test)) //cocos creator里,判断字段不为undefined,null且不为NAN可用 if (cc.isValid(test) && !isNaN(test)) let test_number = parseInt("aaa") //把非数字字符串转换可能出现类型为NAN的情况,需要额外用isNaN判断 判断[]为空 let arr=[] if(!arr.length) 注意: arr==[]返回的是false,不能借此判断 判断{}为空对象 let obj={} if(Object.keys(obj).length == 0); 注意: obj=={}返回的是false,不能借此判断
简写判断 Test ? expr1 : expr2
let b=1 let a = b==1 ? 1 : 2 //等同于 let a; if(b==1){ a=1 } else{ a=2 }
switch…case
let i = 1 switch (i) { case 1: //i==1时走这里 break;//跳出switch语句 case 2: //i==2时走这里 case 3: //i==2或i==3时都会走这里 break; default://其余情况 break; }
9、循环
for循环,遍历数组,或字符串每个元素
continue,break,return使用
//遍历数组,字符串每个元素 let array = [1, 2, 3, 4] for (let i = 0; i < array.length; i++) { const element = array[i]; if (element == 1) { continue;//继续下一个循环 } if (element > 3) { break;//跳出当前for循环 } if (element == 2) { return;//不走下面分代码,直接结束当前方法 } } let str="hello" for (let i = 0; i < str.length; i++) { const element = str[i]; console.log(element) } //依次输出 h e l l o //倒序遍历 for (let i = array.length - 1; i >= 0; i--) //遍历数组 //forEach会把所有元素遍历一遍,不会中途停止 array.forEach(element => { if (element == 1) return//转到下一层遍历 //continue无效 });
for in循环,遍历数组或对象
//遍历数组或对象 let obj = { a: 1, b: 2 } for (const key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { const element = obj[key]; //类似for,可以用break,continue,return } }
// while 循环 // while 语句在给定条件为 true 时,重复执行语句或语句组。循环主体执行之前会先测试条件。 let a = 1 while (1) {//一直执行 a++ if (a == 10) return//直到此处返回,递归会用到 }
10、函数
class testClass { a = 1; fun() { //箭头函数 let fun2 = () => { // 执行代码 console.log(this.a) //输出1,this默认指向当前类 } } }
cocos creator基础知识
官方文档
编辑器里运行脚本代码
0、看官方文档,安装软件,创建工程,创建TS脚本,创建场景,挂载脚本
1、生命周期
onLoad -> onEnable -> start -> update -> lateUpdate -> onDisable -> onDestroy
同一个节点上挂载的组件,在上方的先执行
可在脚本里设置executionOrder,控制脚本生命周期执行顺序,
默认都为0,越小的先执行,可为负数
onLoad//初始化,节点首次激活时(初始化设置父节点后)触发时候调用,active为false时也会调用 onEnable//当组件的 enabled 属性从 false 变为 true 时,node.active=true时候 start//开始,顺序在onLoad后,节点首次激活时触发之后调用,active为false时不会调用 update//每帧调用 lateUpdate//每帧调用,顺序在update后 onDestroy//当组件或者所在节点调用了 destroy() onDisable//当组件的 enabled 属性从 true 变为 false 时,node.active=false时候 当初始化节点后立即调用脚本里某方法,该方法会先于所有生命周期执行
2、节点,创建,销毁,查找
节点就是界面上每个
//创建节点 let node:cc.Node=cc.instantiate(this.target);//复制节点或者实例化预制体 node.active=false; node.parent=parent;//设置父节点 node.setPosition(0,0); node.active=true; //可以在vscode里node.看看cc.Node里面有哪些属性 //销毁节点 node.opacity=0; node.active=false; node.destroy(); //查找节点 var childrenArr = this.node.children;//获取所有子节点,返回节点数组 var node = this.node.getChlidByName("name");//根据名字遍历一级子节点,返回第一个节点名为name的 var tagent1 = cc.find("parent/node", this.node);//按照节点名,从当前路径开始查找 var tagent2 = cc.find("parent/node");//只传一个参数时,按照节点名,从场景根节点开始
3、组件
//组件获取 //获取当前节点其他组件,this.node.getComponent===this.getComponent var label = this.getComponent(cc.Label);//当前节点上cc.Label组件 var move = this.getComponent("move");//获取用户自定义组件(通过脚本名 var label = this.getComponentInChildren(cc.Label);//子节点里第一个为cc.Label的
4、加载场景
//预加载 cc.director.preloadScene("table", function () { cc.log("Next scene preloaded"); }); //加载 cc.director.loadScene("MyScene");
5、资源加载
本地resources加载资源,cc.assetManager.releaseAsset释放资源
//加载本地图片 cc.resources.load("assets/image", cc.SpriteFrame, (err, spriteFrame: cc.SpriteFrame) => { node.getComponent(cc.Sprite).spriteFrame = spriteFrame; }); //加载远程图片,远程 url 带图片后缀名 var remoteUrl = "/zb_users/upload/2024/csdn/someres.png"; cc.assetManager.loadRemote(remoteUrl, (err, texture) => { if (err) { console.error(err); return } node.getComponent(cc.Sprite).spriteFrame = new cc.SpriteFrame(texture); }); //释放资源 let spriteFrame=node.getComponent(cc.Sprite).spriteFrame node.getComponent(cc.Sprite).spriteFrame=null; cc.assetManager.releaseAsset(spriteFrame)
6、自定义事件发射监听
//事件监听 this.node.on('say-hello', (event)=>{ this._sayHello(event); }, this); _sayHello(){ cc.log("接收消息",event); } //事件关闭 this.node.off('say-hello', this._sayHello, this); //事件派发 this.targetNode.emit('say-hello', 'Hello, this is Cocos Creator');
7、内置事件
点击事件,触摸事件,鼠标事件,键盘事件
//监听里的代码,使用了外部节点/脚本,需要判断是否还存在再执行,否则会报错
//触摸事件 this.node.on(cc.Node.EventType.TOUCH_START,(t)=>{ cc.log("点击了"); //cc.Node监听的节点 }, this) //手机触摸 cc.Node.EventType.TOUCH_START// 按下时事件 cc.Node.EventType.TOUCH_MOVE// 按住移动后事件 cc.Node.EventType.TOUCH_END // 按下后松开后事件 cc.Node.EventType.TOUCH_CANCEL // 按下取消事件 this.touchNode.on(cc.Node.EventType.TOUCH_START, this.touchStartEvent, this); this.touchNode.on(cc.Node.EventType.TOUCH_MOVE, this.touchMoveEvent, this); this.touchNode.on(cc.Node.EventType.TOUCH_END, this.touchEndEvent, this); this.touchNode.on(cc.Node.EventType.TOUCH_CANCEL, this.touchEndEvent, this); //鼠标点击 cc.Node.EventType.MOUSE_DOWN//当鼠标在目标节点区域按下时触发一次 cc.Node.EventType.MOUSE_ENTER//当鼠标进入目标节点区域 //按下键盘按键 cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN,(t)=>{ //cc.Node=监听的节点 cc.log("点击了");//按任意键显示 switch (event.keyCode) { //判定哪个按键 case cc.macro.KEY.a: console.log('Press a key a'); break; case cc.macro.KEY.d: console.log('Press a key d'); break; } });
8、动作系统tween
cc.tween(node) .to(1, { position: cc.v3(100, 100), rotation: 360 }, { easing: 'sineOutIn'}) //.to(执行时间, { 执行改变属性,可同时改变多个属性 }, { easing: 内置缓动动画}) .to(1, { scale: 2 }, { easing: t => t*t; }) //按顺序执行, { easing: t => t*t; }自定义缓动动画 .delay(1)//延迟一秒 .call(() => { //回调函数 }) .union()//将上述合为一个 .repeat(2)//重复两次 .repeatForever()//一直重复 .start()//调用这个才会执行 // 先创建一个缓动作为模板 let tween = cc.tween().to(4, { scale: 2 }) // 复制 tween,并使用节点 Canvas/cocos 作为 target tween.clone(node).start() //插入其他的缓动到队列中 let scale = cc.tween().to(1, { scale: 2 }) let rotate = cc.tween().to(1, { rotation: 90}) let move = cc.tween().to(1, { position: cc.v3(100, 100, 100)}) // 先缩放再旋转 cc.tween(this.node).then(scale).then(rotate).start() //并行执行缓动 let tweenEvent = cc.tween(this.node) // 同时执行两个 cc.tween .parallel( cc.tween().to(1, { scale: 2 }), cc.tween().to(2, { position: cc.v2(100, 100) }) ) .call(() => {//都执行完了才会执行这个 console.log('All tweens finished.') }) .start() //停止当前动画 tweenEvent.stop() //停止所有缓动动作 node.stopAllActions()
9、计时器schedule,setTimeout
schedule
//挂载脚本的页面隐藏时(active=false),会暂停执行, //依附的节点销毁后,不执行 //计时器里的代码,使用了外部节点/脚本,需要判断是否还存在再执行,否则会报错 //只执行一次 this.scheduleOnce(() => { //计时器里的代码,需要判断节点是否还存在 if (cc.isValid(node)) node.active = false }, 1) this.schedule(() => { this.doSomething(); }, 5,3,10);//5:以秒为单位的时间间隔,3:重复次数,10:延时开始时间,3,5可省略
//脚本所在节点销毁,隐藏还会执行,时间单位为毫秒 setTimeout(() => { }, 1000)
10、网络
//短链接 Send(urlData, reqData, succCallback?, failCallback?) { let xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (xhr.readyState == 4) { // 接收完毕 if (xhr.status >= 200 && xhr.status < 400) {// 响应中的数字状态码:表示为有效响应,成功的请求 var response = xhr.responseText; // 对文本请求的响应 if (response) { console.log("请求" + urlData + "成功,返回数据"); var responseJson = JSON.parse(response); // 解析完的json 文件再返回 回调函数 console.log(responseJson) if (succCallback) succCallback(responseJson); } else { console.log("无返回数据"); if (succCallback) succCallback(false); } } else { console.log("请求失败"); if (failCallback) failCallback(false); } } }; let url = Net.ip + urlData; console.log("开始请求,地址 ", url); console.log(reqData); xhr.open("POST", url, true); xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); //告诉服务器如何解析我的内容 xhr.setRequestHeader("Content-Type", "json/application"); xhr.setRequestHeader('Access-Control-Allow-Origin', '*'); xhr.setRequestHeader('Access-Control-Allow-Methods', 'GET, POST'); xhr.setRequestHeader('Access-Control-Allow-Headers', 'x-requested-with,content-type'); xhr.send(JSON.stringify(reqData)); return; } sendAccounts(data: any, cb?: Function, fb?: Function) { if (!data) return; this.Send("/player", data, (data) => { console.log("发送成功") if (cb) cb(data); }, () => { console.log("发送失败") if (fb) fb(); }) }
10、常用Math函数
//常用方法,函数 //number处理 let number = 1.4242 //随机数 Math.random()//返回0-1的小数 //取整 Math.floor(number)//返回1,向下取整,整数不变 Math.ceil(number)//返回2,向上取整,整数不变 //取绝对值 Math.abs(-112) //字符串处理 //字符串转数字 let num = Number("1313.232")//返回number类型的1313.232,如果传入字母等非数字会返回NAN //判断是否为NAN isNaN(num) //正则替换第一个, "1,2,3".replace(",", ",") //正则替换所有, "1,2,3".replace(/,/g, ',') //json数据处理 let data = { name: "2323", id: 2323 } //json数据转字符串 let strData = JSON.stringify(data) //字符串转json数据,格式不规范会报错 try { data = JSON.parse(strData)//返回json{ name: "2323", id: 2323 } } catch (error) { console.log(error) } //角度,弧度 //根据角度获取弧度 let angle = 45 let radian = -(Math.PI / 180 * (angle)); Math.sin(radian) //节点坐标相关 //节点坐标转换 function nodeToCanvasSpace(node: cc.Node) { if (!cc.isValid(node)) return cc.v2(0, 0); //转换node当前节点坐标到世界坐标 let pos = node.convertToWorldSpaceAR(cc.v2(0, 0)); //转换node节点下cc.v2(100, 22)坐标到世界坐标 //pos = node.convertToWorldSpaceAR(cc.v2(100, 22)); //转换世界坐标到节点坐标 return cc.find('Canvas').convertToNodeSpaceAR(pos); } //两点距离 getDistance(fmPos: cc.Vec2, toPos: cc.Vec2) { if (!fmPos || !toPos || !fmPos.x || !fmPos.y || !toPos.x || !toPos.y) return var distance = fmPos.sub(toPos).mag() return distance; } //根据两点获取角度 getAngle(fmPos, toPos) { var angle = Math.atan2((fmPos.y - toPos.y), (fmPos.x - toPos.x)) //弧度 var theta = angle * (180 / Math.PI); //角度 return theta; } //时间相关 //获取当前时间戳,秒为单位 let time=Math.floor(Date.now() / 1000);