IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> cocos2d拖动组件吸附效果 -> 正文阅读

[游戏开发]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)

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-02-26 12:03:55  更:2022-02-26 12:06:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 16:27:48-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码