LayaAir拖拽移动对象并吸附(附源码)

前言: 拖拽移动对象是2D休闲小游戏中常用的一个功能,典型代表例如《植物大战僵尸》中,种植植物的表现形式,拖拽植物卡片种植到相应的地点。今天介绍一下在Laya项目中实现这一功能。
该功能实现参照了 :Egret拖拽对象与吸附 https://blog.csdn.net/u013617851/article/details/83867180

思路: 在 Laya 中实现拖拽对象,需要用到MOUSE_MOVE事件的监听,触摸移动触发MOUSE_MOVE,此时计算触摸移动的大小,让拖拽对象也进行相应的移动。
演示:
debug
开发:

  1. 首先创建一个页面,页面上摆放好目标格子。我这边摆了9个,编号分别是 panel_00 ~panel_08。然后动态加载出来我们要拖拽的材料:
    initUI() {
        for (let i = 0; i < 3; i++) {
            let pd: ProductItem = new ProductItem(false);
            this.bottomGp.addChild(pd);
        }
    }
  1. 在拖拽开始的时候,在材料的位置实例化出来一个同样的材料对象,并且将坐标转化为世界坐标,并添加监听事件:
    private curTargetObj: ProductItem;
    private storeX: number; //拖拽对象的初始位置X
    private storeY: number; //拖拽对象的初始位置Y
    private PointX: number = 100; //吸附点坐标X
    private PointY: number = 100; //吸附点坐标Y

    public instantiatePro(obj: ProductItem, e) {
        this.curTargetObj = new ProductItem(true);
        this.curTargetObj.img_product.skin = obj.img_product.skin;
        this.curTargetObj.x = obj.localToGlobal(new Laya.Point()).x;
        this.curTargetObj.y = obj.localToGlobal(new Laya.Point()).y;

        this.onMoveBegin(e);

        this.initTargetObjBindEvent();
        this.addChild(this.curTargetObj);
    }

    private initTargetObjBindEvent() {
        this.curTargetObj.on(Laya.Event.MOUSE_MOVE, this, this.onMoving);
        this.curTargetObj.on(Laya.Event.MOUSE_UP, this, this.onMoveEnd);
    }
    
    private XTouch: number;
    private YTouch: number;
    private onMoveBegin(e): void {
        //Obj对象的坐标
        this.storeX = this.curTargetObj.x;
        this.storeY = this.curTargetObj.y;
        //想办法记录鼠标移动的记录的坐标
        this.XTouch = e.stageX;
        this.YTouch = e.stageY;
    }
  1. 在拖拽的过程中让实例化出来的对象跟随鼠标(手指)的移动而移动:
private onMoving(e): void {
        this.curTargetObj.x = this.storeX + (e.stageX - this.XTouch);
        this.curTargetObj.y = this.storeY + (e.stageY - this.YTouch);
    }
  1. 当移动到适当的位置后松开鼠标(手指),对象会搜索最近的格子所在的位置,并以缓动动画的形式吸附过去,如果停止的位置距离目标区域差距过大,则回到起始的位置,并自动销毁。
private onMoveEnd(): void {
        // 拖拽结束后,计算坐标
        let self = this;
        let closePoint: number = 0;//第几个point是最近的
        let closelen: number = 1000;//设定个阈值
        let zoneMin: number = 750;
        let zoneMax: number = 1150;
        let len: number = 0;
        if (self.curTargetObj.y < zoneMin || self.curTargetObj.y > zoneMax) {
            // 如果不满足吸附条件,就回到原来位置,并且销毁/
            this.PointX = this.storeX;
            this.PointY = this.storeY;
            Laya.timer.once(400, this, () => {
                this.curTargetObj.destroy();
            });
        } else {
            // 吸附到最近的地方
            for (let i: number = 0; i < 9; i++) {
                //两个Obj距离公式
                len = Math.sqrt(Math.pow((self["panel_0" + i].x - self.curTargetObj.x), 2) + Math.pow((self["panel_0" + i].y - self.curTargetObj.y), 2));   //Math.pow(2,4);表示2的4次方,等于16 ,Math.sqrt(x);
                if (len < closelen) {
                    closelen = len;
                    closePoint = i;
                }
            }
            this.PointX = this["panel_0" + closePoint].x + 50;  // 相对于目前的模块居中
            this.PointY = this["panel_0" + closePoint].y;
        }
        Laya.Tween.to(self.curTargetObj, { x: self.PointX, y: self.PointY }, 400, Laya.Ease.cubicOut);
    }

这里计算距离的公式实际上就是求两点之间直线距离的公式:
在这里插入图片描述
最后送上整个项目的打包源码:
LayaAir拖拽移动对象并吸附源码

如果这篇文章帮到了你,或者看完之后有了思路,那就给俺点个赞呗,可以让更多的人看到这篇文章,顺便激励下我,嘻嘻。
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值