我们在使用cocos creator时有时候需要实现鼠标去拖动一个节点移动,这本来是很简单的问题,只需要监听节点事件在按下的时候改变状态为true、移动的时候判断状态是为true就改变节点的位置、抬起的时候再把状态改为false就好了。
js
export class test extends Component {
// 状态
isDown: boolean;
start() {
// 是否按下
this.isDown = false;
// 添加按下事件
this.node.on(Node.EventType.MOUSE_DOWN, this.onDown, this);
// 添加抬起事件
this.node.on(Node.EventType.MOUSE_UP, this.onUp, this);
// 添加移动事件
this.node.on(Node.EventType.MOUSE_MOVE, this.onMove, this);
// 添加移出事件
this.node.on(Node.EventType.MOUSE_LEAVE, this.onUp, this);
}
// 按下事件
onDown(e: EventMouse) {
this.node.setSiblingIndex(10);
this.isDown = true;
}
// 抬起事件
onUp(e: EventMouse) {
this.isDown = false;
}
// 移动事件
onMove(e: EventMouse) {
if (this.isDown) {
// 获取节点偏移量
const delta = e.getUIDelta();
// 获取当前位置
const position = this.node.position;
// 修改节点的位置
this.node.setPosition(position.x + delta.x, position.y + delta.y);
}
}
update(deltaTime: number) {}
}
但是如果我们作用的是一个不规则图形就有问题了。
如上图所示,红色部分是图形的透明部分,即使你拖拽的是图形的透明部分,图形也会被拖拽移动,为了解决这个问题,可以为节点添加PolygonCollider2D组件,组件会自动根据图形生成轮廓,这样就可以根据轮廓去判断点击的定位点是透明区域部分还是图形部分了。
剩下的就是代码了,看如下代码。
js
import {
_decorator,
Component,
EventMouse,
Node,
UITransform,
Intersection2D,
PolygonCollider2D,
v3,
v2
} from "cc";
const { ccclass, property } = _decorator;
@ccclass("test")
export class test extends Component {
// 状态
isDown: boolean;
start() {
// 是否按下
this.isDown = false;
// 添加按下事件
this.node.on(Node.EventType.MOUSE_DOWN, this.onDown, this);
// 添加抬起事件
this.node.on(Node.EventType.MOUSE_UP, this.onUp, this);
// 添加移动事件
this.node.on(Node.EventType.MOUSE_MOVE, this.onMove, this);
// 添加移出事件
this.node.on(Node.EventType.MOUSE_LEAVE, this.onUp, this);
}
// 按下事件
onDown(e: EventMouse) {
// 获取碰撞组件
const collider = this.node.getComponent(PolygonCollider2D);
// 如果没有碰撞组件直接返回
if (!collider) {
// 设置当前节点在父节点的 children 数组中的位置,使节点保持在最高层,不会被其他的节点覆盖
this.node.setSiblingIndex(10);
this.isDown = true;
return;
}
// 点击位置的坐标
const downPoint = e.getUILocation();
// 把UI窗口内的坐标位置转换成节点为中心点的坐标
const nodePoint = this.node.getComponent(UITransform).convertToNodeSpaceAR(v3(downPoint.x,downPoint.y));
// 多边形的顶点
const points = collider.points;
// 获取点击位置的坐标是否在多边形内
const is = Intersection2D.pointInPolygon(v2(nodePoint.x,nodePoint.y), points);
if (is) {
this.node.setSiblingIndex(10);
this.isDown = true;
// 如果点击的图形区域设置事件不可穿透
e.preventSwallow = false;
}else{
// 如果点击的是透明区域设置事件可穿透
e.preventSwallow = true;
}
}
// 抬起事件
onUp(e: EventMouse) {
this.isDown = false;
}
// 移动事件
onMove(e: EventMouse) {
if (this.isDown) {
// 获取节点偏移量
const delta = e.getUIDelta();
// 获取当前位置
const position = this.node.position;
// 修改节点的位置
this.node.setPosition(position.x + delta.x, position.y + delta.y);
}
}
update(deltaTime: number) {}