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 }"
let b=obj.a
b=5;
//输出b =5,输出obj.a =2
//常数赋值只传了值
obj = null;
//输出 obj.a失败,会报错
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 = "http://unknown.org/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);