前言
更新中……
一边看Cocos Creator零基础小白超神教程一边练手时发现有很多api都改变了。记录下来节省后来人时间
3.8推荐看该教程,比百度好使
一方面也是知识点零散不好做笔记
源码位置:安装目录下的resources\resources\3d\engine
坑
- 顶层canvas无法触发事件
- 触摸移动使用世界坐标系
setWorldPosition
new Vec3()
可以简写成v3()
- 经测试,setPosition是相对父元素的锚点,position获取的坐标是相对于父节点锚点的坐标,setWorldPosition是相对于左下角(世界原点)
- 解决图片滚动空隙:卡顿导致deltaTime过大,所以直接在setposition的时候给一个更小的y值就行
- 用scale做动画,z轴不能设置为0,否则无法点击
- position的add方法会改变position而不是返回一个新的v3,源码为证,又没能在文档找到说法。还必须转成世界坐标系!
- uitransform的大小不能设置为0,不然会自动改成300*200!
- 图片资源的路径必须要在最后加spriteFrame
- 慎用auto release assets自动资源释放,报错
Object.updateUVs (…/cocos-js/cc.8b346.js:1:1068082)
正文
移动位置的三种方式
setPosition
:建议使用v3避免重复实例化
// getPosition 可以传入out参数,则无需实例化,节省开销
let bulletPos = bullet.getPosition();//get返回的是一个私有变量,所以可以直接赋值修改了
bulletPos.y += 100;
3
// set方法本质是调用了setPosition方法
bullet.position = v3(this.node.position.x, this.node.position.y + 100);
触摸移动方案
input.on
: 监听所有node.on
:监听范围内
不同api的场景:
getUILocation
:UI 窗口内的坐标位置getLocation
: 世界坐标系getLocationInView
:游戏窗口内的坐标位置对象convertToNodeSpaceAR
:世界坐标转相对
触摸移动
- getLocation获取绝对定位,设置坐标时用convertToNodeSpaceAR转为相对
// 获取父节点的UITransform组件
@property(Node)
private map: Node = null;//map选择背景节点
start() {
this.map.on(Node.EventType.TOUCH_MOVE, (event: EventTouch) => {
const parentUITransform = this.map.getComponent(UITransform);
let touchPos = new Vec3(event.getLocationX(), event.getLocationY(), 0); // 获取触摸点的世界坐标
let localPos = new Vec3();
parentUITransform.convertToNodeSpaceAR(touchPos, localPos); // 转换到节点局部坐标
this.node.setPosition(localPos.x, localPos.y);
});
}
- 直接设置世界坐标位置
input.on(Input.EventType.TOUCH_MOVE, (event: EventTouch) => {
this.node.setWorldPosition(event.getLocationX(), event.getLocationY(), 0);
});
- 只由玩家组件触发(3.5、3.6有版本差别):(我的选择)
另一篇博客详细说明
this.node.on(Input.EventType.TOUCH_MOVE, (touch: EventTouch) => {
this.node.setWorldPosition(v3(touch.getUILocation().x, touch.getUILocation().y));
});
碰撞检测
- 注册回调事件
- 编写钩子函数
- 功能裁剪中使用内置物理组件则无需添加刚体
onLoad() {
//获取碰撞组件父组件
let collider = this.node.getComponent(Collider2D);
collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
}
// 只在两个碰撞体开始接触时被调用一次
// 只在两个碰撞体开始接触时被调用一次
onBeginContact (selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {
// 物理过程之后再销毁,以免报错
director.once(Director.EVENT_AFTER_PHYSICS, () => {
otherCollider.node.destroy();
}, this)
}
2d物理射线
- 经测试确实会忽略自身节点
let distance = 100; // 射线长度
let objs = new Vec2(this.node.getWorldPosition().x, this.node.getWorldPosition().y); // 起点
let obje = new Vec2(this.node.getWorldPosition().x, this.node.getWorldPosition().y + distance * this.dir.y); // 终点 --向量数乘
let results = PhysicsSystem2D.instance.raycast(objs, obje); // 遍历检测信息