在Cocos2d中拖动组件并吸附到节点
最近在学习制作小游戏,要实现一个拖动吸附效果,这里简单实现一下

代码实现
定义节点和函数功能
在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);
// 新建一个位移动作,动画持续时间为0.3s
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)
在Cocos2d中拖动组件并吸附到节点的更多相关文章
- [置顶] Flex中Tree组件无刷新删除节点
在Tree组件中经常要删除某个节点,而删除之后重新刷新加载该Tree组件会影响整个操作效果和效率,因此,无刷新删除就比较好,既删除了节点也没有刷新tree,而使Tree的状态处于删除之前的状态. 无刷 ...
- 第一百九十三节,jQuery EasyUI,Draggable(拖动)组件
Draggable(拖动)组件 学习要点: 1.加载方式 2.属性列表 3.事件列表 4.方法列表 本节课重点了解 EasyUI 中 Draggable(拖动)组件的使用方法,这个组件不依赖于其 他组 ...
- 微信开发新增拖动组件--movableview介绍
小程序的更新中,也新增了一个UI组件,它就是视图组件movable-view,它需要配合movable-area来一起使用.简单来说,它就是一个支持在指定区域内可以拖动内容的容器.我们来看一个简单的示 ...
- [刘阳Java]_easyui-draggable拖动组件_第4讲
easyui-draggable的拖动组件还是比较好用的,它能够快速地实现网页中元素的拖动效果 实现easyui-draggable拖动组件有两种方式:纯HTML方式和JS方式 纯HTML方式实现拖动 ...
- android中四大组件之间相互通信
好久没有写有关android有关的博客了,今天主要来谈一谈android中四大组件.首先,接触android的人,都应该知道android中有四大组件,activity,service,broadca ...
- Android ScrollView中的组件设置android:layout_height="fill_parent"不起作用的解决办法
例子,在ScrollView下加入的组件,无论如何也不能自动扩展到屏幕高度. 布局文件. [html] <?xml version="1.0" encoding=" ...
- 如何在Vue2中实现组件props双向绑定
Vue学习笔记-3 前言 Vue 2.x相比较Vue 1.x而言,升级变化除了实现了Virtual-Dom以外,给使用者最大不适就是移除的组件的props的双向绑定功能. 以往在Vue1.x中利用pr ...
- cocos2d中的可见性检测
游戏的在进行一次渲染的时候,通常会提交大量的渲染对象给gpu.在这些需要渲染的对象中,并不是所有对象都会出现镜头中,即有一部分对象是不可见的. 通常有两种方式来完成不可见对象的剔除工作: (1)直接交 ...
- java中解决组件重叠的问题(例如鼠标移动组件时)
java中解决组件覆盖的问题! 有时候在移动组件的时候会出现两个组件覆盖的情况,但是你想让被覆盖的组件显示出来或者不被覆盖! 在设计GUI时已经可以定义组件的叠放次序了(按摆放组件的先后顺序) ...
- Cocos2d 中的Sprite大小调整问题
以前用UIImageView,比如 UIImageView *view = [[UIImageViewalloc] initWithImage:[UIImageimageNamed:@"b ...
随机推荐
- 历时 4 个月,CabloyJS 4.21震撼发布,应对大型项目开发
引言 凡是可以用 JavaScript 来写的应用,最终都会用 JavaScript 来写 | Atwood 定律 目前市面上出现的大多数与 NodeJS 相关的框架,基本都将 NodeJS 定位在工 ...
- Python语言Numpy包之Meshgrid 函数
Meshgrid 函数的基本用法 在 Numpy 的官方文章里, meshgrid 函数的英文描述也显得文绉绉的,理解起来有些难度.可以这么理解, meshgrid 函数用两个坐标轴上的点在平面上画网 ...
- HarmonyOS线上Codelabs系列挑战赛第二期:调用三方库,制作酷炫的视觉效果
HarmonyOS线上Codelabs系列挑战赛正如火如荼进行中,开发者们可以通过体验基于HarmonyOS特性和能力的应用开发,快速构建有趣.有用的应用程序.火速加入,与众多开发者一起碰撞想法, ...
- 动态规划(六)——树形dp
树形dp,又称树状dp,即在树上进行的dp,在设计动态规划算法时,一般就以节点从深到浅(子树从小到大)的顺序作为dp的"阶段",dp的状态表示中,第一维通常是节点编号(代表以该节点 ...
- triple loss
Triplet Loss是深度学习中的一种损失函数,用于训练差异性较小的样本,如人脸等, Feed数据包括锚(Anchor)示例.正(Positive)示例.负(Negative)示例,通过优化锚示例 ...
- docker 应用篇————容器卷[十一]
前言 简单介绍一下容器卷. 正文 我们发现一个文件,就是什么呢? 就是说因为我们的容器一但删除那么什么都没有了. 那么如何能够不删除呢?那么可以使用容器卷. 比如说系统我们容器内的/usr 使用我们的 ...
- Tencent 闲聊对话机器人接口调用,画像:设计员小白
from datetime import datetime import time import requests from hashlib import md5 from urllib import ...
- 还原数据库从远端环境到本地开发环境,数据SINGLE_USER问题
要还原到本地开发环境,首先要detach本地数据库或者是删除本地数据库,不然提示在使用中还原不了,但是搞过几次去做detach和drop数据库时,总是不成功,最后还出现个单用户模式,莫名奇妙 为此网上 ...
- 力扣176(MySQL)-第二高的薪水(中等)
题目: id 是这个表的主键.表的每一行包含员工的工资信息. 编写一个 SQL 查询,获取并返回 Employee 表中第二高的薪水 .如果不存在第二高的薪水,查询应该返回 null . 查询结果如下 ...
- 力扣25(java&python)-K 个一组翻转链表(困难)
题目: 给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表. k 是一个正整数,它的值小于或等于链表的长度.如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺 ...