最近在学习制作小游戏,要实现一个拖动吸附效果,这里简单实现一下
代码实现
定义节点和函数功能
在properties 里新建一个对象,用来接收目标区域的节点
properties:{
sense: {
defaule: null,
type: cc.Node,
}
}
然后在小车节点里绑定这个脚本,将要测试的目标节点拖动到属性检查器的sense
这里用小车来表示要移动的组件,先在onload() 内定义小车组件,设置位置,以及定义三个触摸事件函数
onload() {
this.carPos = cc.v2(0, 0);
this.node.setPosition(this.carPos.x, this.carPos.y);
this.origin = this.node.convertToWorldSpace(cc.v2(0, 0));
this.node.on("touchstart", this.touchStart, this);
this.node.on("touchmove", this.touchMove, this);
this.node.on("touchend", this.touchEnd, this);
}
然后就是对三个触摸事件定义
touchStart(event) {
let touchPos = event.getLocation();
let posInNode = this.worldConvertLocalPoint(this.node, touchPos);
let target = this.node.getContentSize();
let rect = cc.rect(0, 0, target.width, target.height);
if (rect.contains(posInNode)) {
this.touchTile = this.node;
}
console.log(posInNode.x + " " + posInNode.y);
},
touchMove(event) {
if (this.touchTile) {
this.touchTile.setPosition(this.touchTile.x + event.getDelta().x ,
this.touchTile.y + event.getDelta().y);
}
},
touchEnd(event) {
let touchPos = this.touchTile.convertToWorldSpaceAR(cc.v2(0, 0));
let posInNode = this.worldConvertLocalPoint(this.sense1, touchPos);
let target = this.sense1.getContentSize();
let correctValue = cc.v2(this.sense.width / 2 - this.origin.x - this.node.width / 2, this.sense.height / 2 - this.origin.y - this.node.height / 2);
let rect = cc.rect(0, 0, target.width, target.height);
if (rect.contains(posInNode)) {
console.log("---endPos");
let targetPos = this.sense1.convertToWorldSpace(cc.v2(correctValue));
let action = cc.moveTo(0.3, targetPos);
this.touchTile.runAction(action);
} else {
console.log("----go back");
let action = cc.moveTo(0.3, this.carPos);
this.touchTile.runAction(action);
}
this.touchTile = null;
},
worldConvertLocalPoint(node, worldPoint) {
if (node) {
return node.convertToNodeSpace(worldPoint);
}
return null;
}
最终效果
拖入目标区域
没拖到指定区域
修正
这里要把小车放到目标区域的正中心,需要对坐标进行修正。在cocos creator里,有节点坐标和世界坐标这两个概念
而在属性检查器里,我们所设置的position ,也就是锚点的位置,是相对于父节点的,例如图中我把position 设为0和0,就是相对于父节点,该组件定位在父节点的几何中心。
那么,哪些坐标值和最终放置的位置坐标有关联呢?
在没有修正之前,把targetPos 的值设为this.sense.convertToWorldSpace(cc.v2(0, 0)) ,拖动后的效果如下图
并且log打印目标位置的坐标,水平值离屏幕宽度一半还有一定的差距,这时我又打印了拖动结束后小车的坐标值,好家伙,我轻点小车没有拖动,控制台输出的坐标值为(0,0) ,而图中很明显,小车的位置不在世界坐标的原点上,即此时小车的坐标参照点为小车的初始位置
那问题来了,怎么修正?
只需在onload() 中定义一个变量储存小车的世界坐标值 this.origin = this.node.convertToWorldSpace(cc.v2(0, 0)) ,然后在touchEnd() 中新定义一个向量值correctValue ,新建一个向量cc.v2(-this.origin.x, -this.origin.y) ,并返回给correctValue ,再将correctValue 转化为世界坐标赋给targetPos ,此时小车会自动吸附到目标区域左下角,展现的效果如下
如果要把小车定位到目标区域的正中央,还需要考虑小车组件和目标区域的长宽,相应地,correctValue 应该设为cc.v2(this.sense.width / 2 - this.node.width / 2 - this.origin.x, this.sense.height / 2 - this.node.height / 2 - this.origin.y)
参考链接
(61条消息) CocosCreator的拖动小游戏主要逻辑_天才派大星 !的博客-CSDN博客_cocos creator 拖动
原文出处: cocos2d拖动组件吸附效果 | Jayden’s Blog (jaydenchang.top)
|