cocos creator 学习笔记

197 阅读4分钟
  • 使用的编程语言是: typescript

制作图集

使用texture picker 制作图集

动态加载资源

官方文档: 文档地址 在使用 resources.load加载精灵(SpriteFrame)时出现的问题: 根据官方的方式 一直报错 , 无论如何都报错 , 具体原因不详 , 但是如果使用loadDir却是可以加载的 , 加载的结果是数组 替代的方法: 加载精灵图集 SpriteAtlas 代码:

resources.load("test_img/sprite",SpriteAtlas,(err,res)=>{
        this.getComponent(Sprite).spriteFrame = res.getSpriteFrame("land");
    })

后来经过论坛发帖得出: 3.x后的版本的使用方式应该是这样的:

resources.load("test_img/land/spriteFrame",SpriteFrame,(err,res)=>{
        this.getComponent(Sprite).spriteFrame = res
    })

在编辑器中填写属性

// 在类中使用@property 即可在编辑器中填写需要的数值了括号中包含的是数据的类型
@property(Number)
level:number = 1;

动态加载节点

  1. 创建节点
  2. 添加组件
  3. 将节点加载到父节点中

监听键盘鼠标事件

引入: input , Node,EventMouse,Input,input,KeyCode
// 鼠标监听 触摸事件类似 ,类型不同
this.node.on(Node.EventType.MOUSE_DOWN,function(event:EventMouse){
    if(event.getButton() === EventMouse.BUTTON_LEFT){
        console.log("左键")
    }else if(event.getButton() === EventMouse.BUTTON_RIGHT){
        console.log("右键");
    }
})
// 键盘监听
input.on(Input.EventType.KEY_DOWN,(event:EventKeyboard)=>{
    console.log(event.keyCode === KeyCode.KEY_A);
},this)

KeyCode Input Node Event EventMouse EventKeyboard EventTouch

碰撞检测

在使用碰撞监测的时候 , 如果 项目 -> 项目设置 -> 功能裁剪 -> 2D -> 2D物理系统 的选项是: 基于Box2D的2D物理系统 , 在添加碰撞检测的时候 一定要添加金刚(RigidBody2D) , 并且勾选Enable Contact Listener

2D物理系统 碰撞回调 碰撞组件

start () {
    // 注册单个碰撞体的回调函数
    let collider = this.getComponent(Collider2D);
    if (collider) {
        collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
        collider.on(Contact2DType.END_CONTACT, this.onEndContact, this);
        collider.on(Contact2DType.PRE_SOLVE, this.onPreSolve, this);
        collider.on(Contact2DType.POST_SOLVE, this.onPostSolve, this);
    }

    // 注册全局碰撞回调函数
    if (PhysicsSystem2D.instance) {
        PhysicsSystem2D.instance.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
        PhysicsSystem2D.instance.on(Contact2DType.END_CONTACT, this.onEndContact, this);
        PhysicsSystem2D.instance.on(Contact2DType.PRE_SOLVE, this.onPreSolve, this);
        PhysicsSystem2D.instance.on(Contact2DType.POST_SOLVE, this.onPostSolve, this);
    }
}
onBeginContact (selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {
    // 只在两个碰撞体开始接触时被调用一次
    console.log('onBeginContact');
}
onEndContact (selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {
    // 只在两个碰撞体结束接触时被调用一次
    console.log('onEndContact');
}
onPreSolve (selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {
    // 每次将要处理碰撞体接触逻辑时被调用
    console.log('onPreSolve');
}
onPostSolve (selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {
    // 每次处理完碰撞体接触逻辑时被调用
    console.log('onPostSolve');

}

利用碰撞体检测碰撞位置

对于矩形或者一两条平行边的碰撞 , 会产生两个碰撞点 , 通过这两个碰撞点可以确定碰撞边 , 如果非平行边 , 一个碰撞点几乎就能确定碰撞的方位了

拿两个矩形来讲:

  • 当两个矩形相互碰撞 , 会出现两个碰撞点
  • 如果在左右两侧,两个碰撞点的x相同
  • 然后判断碰撞点的x是否小于碰撞物体的坐标x
  • 是则为左否则为右
  • 上下判断同理
public getContactPosition(selfCollider:Collider2D,contact:IPhysics2DContact,callback:Function=(res:"top"|"bottom"|"right"|"left")=>{}):void{
        let points = contact.getWorldManifold().points;
		// 多点判定
        if(points.length > 1){
            let {x:x1,y:y1} = points[0]
            let {x:x2,y:y2} = points[1]
			// 都用世界坐标
            let {x:sx,y:sy} = selfCollider.node.worldPosition;
            // 横/纵向碰撞点和当前点的世界坐标差
            let [h,v] = [x1-sx,y1-sy]
            if(h <= 0 && x1==x2){
                callback("left")
                return;
            }else if(v <= 0 && y1==y2){
                callback("bottom")
                return;
            }else if(h >=0 && x1==x2){
                callback("right")
                return;
            }else if(v >0 && y1==y2){
                callback("top")
                return;
            }
        }
        callback(null)
    }

动画相关

let animation:Animation = this.getComponents(Animation);
// 播放动画
animation.play("动画名称")
// 监听动画, 监听到某个动画完成, 然后执行某项功能
animation.on(Animation.EventType.FINISHED,(status,res:AnimationState)=>{
    if(res.name == "动画名称"){
        coin.destroy();
    }
})

关于坐标系

相关文档

  • 世界坐标系
    • 世界坐标系的原点是视图的左下角(0,0)
    • 相关属性: worldScale 世界坐标系下的缩放 worldRotation 世界坐标系下的旋转,用四元数表示 worldPosition 世界坐标系下的坐标 worldMatrix 世界坐标系变换矩阵
    • 相关方法: setWorldScale 设置世界坐标系下的缩放 setWorldRotationFromEuler 用欧拉角设置世界坐标系下的旋转 setWorldRotation 用四元数设置世界坐标系下的旋转 setWorldPosition 设置世界坐标 getWorldScale 获取世界缩放,注意,尽可能传递复用的 Vec3 以避免产生垃圾。 getWorldRotation 获取世界坐标系下的旋转,注意,尽可能传递复用的 Quat 以避免产生垃圾。 getWorldRT 获取只包含旋转和位移的世界变换矩阵 getWorldRS 获取只包含旋转和缩放的世界变换矩阵 getWorldPosition 获取世界坐标,注意,尽可能传递复用的 Vec3 以避免产生垃圾。 getWorldMatrix 获取世界变换矩阵
  • 相对(本地)坐标系
    • 相对坐标系原点是父级节点的锚点位置
    • 相关属性: scal 本地坐标系下的缩放 rotation 本地坐标系下的旋转,用四元数表示 position 本地坐标系下的坐标 ...

射线检测

		// 新建射线
        let res = PhysicsSystem2D.instance.raycast(this.node.worldPosition,v2(x+50,y));
        let len = res.length;
        if(len){
			// 遍历射线上的目标
            for (let item of res){
                 if(!!(item.collider.tag & 0x100)){
                     this.direction = this.direction == 1?-1:1;
                
                 }
            }
        }
         

从预设体实例化新节点

instantiate