关注

【cocos creator】拖拽排序列表

请添加图片描述

DEMO下载

GameCtrl.ts

import ItemCtrl from "./ItemCtrl";


const { ccclass, property } = cc._decorator;

@ccclass
export default class GameCtrl extends cc.Component {

    @property(cc.Node)
    content: cc.Node = null;
    @property(cc.Node)
    prefab: cc.Node = null;
    arr = []
    //移动速度
    moveSpeed = 0.15
    //排序x间距
    spacingX = 10

    nodePool: cc.Node[] = []

    tempId = 0
    touchId = null
    lastTouchId = null
    isAni = false

    start() {
        //列表数量
        let count = 8
        //初始化列表
        this.isAni = true
        for (let i = 0; i < count; i++) {
            this.scheduleOnce(() => {
                this.addOne()
            }, i * 0.1)
        }
        this.scheduleOnce(() => {
            this.isAni = false
        }, count * 0.1 + this.moveSpeed)
    }

    onAddBtnClick() {
        this.addOne()
    }

    onRemoveBtnClick() {
        if (!this.arr.length) return
        let id = this.lastTouchId
        let index = this.arr.findIndex((value) => { return value.id == id })
        if (index == -1) id = this.arr[0].id
        this.removeOneById(id)
        this.upDateIndexByX(true)
    }

    removeOneById(id) {
        let index = this.arr.findIndex((value) => { return value.id == id })
        if (index == -1) return
        let data = this.arr.splice(index, 1)
        let node: cc.Node = data[0].node
        let toPos = node.position
        if (index == 0) toPos = cc.v3(node.position.x - this.prefab.width / 2, node.position.y)
        cc.tween(node)
            .to(this.moveSpeed, { position: toPos, scale: 1, opacity: 0 })
            .call(() => {
                node.stopAllActions()
                node.active = false
                this.nodePool.push(data[0].node)
            })
            .start()
    }


    addOne(waitTime = 0) {
        let node: cc.Node = this.nodePool.shift()
        if (!node) {
            node = cc.instantiate(this.prefab)
            node.parent = this.content
        }
        node.opacity = 0;
        node.scale = 1
        let pos = this.getItemPos(this.arr.length, this.arr.length + 1)
        let id = this.tempId
        let data = {
            name: id,
            id: id,
            index: id,
            node: node,
            originPos: pos,
            checkPos: pos
        }
        this.arr.push(data);
        node.getComponent(ItemCtrl).initData(data, this)
        node.setPosition(pos)
        node.x = pos.x + this.prefab.width
        node.active = true
        cc.tween(node)
            .delay(waitTime)
            .call(() => {
                this.upDateIndexByX(true)
            })
            .to(this.moveSpeed, { position: node.position, scale: 1, opacity: 255 })
            .start()
        this.tempId++
    }



    /**
     * 获取item排序位置
     * @param i 
     * @param totalCount 
     * @returns 
     */
    getItemPos(i, totalCount) {
        let startX = -(totalCount - 1) * (this.prefab.width + this.spacingX) / 2
        let pos = cc.v2(0, 0)
        pos.x = startX + (this.prefab.width + this.spacingX) * i
        return pos
    }

    getSidePos() {
        let totalCount = this.arr.length
        let startX = -(totalCount - 1) * (this.prefab.width + this.spacingX) / 2
        let pos = cc.v2(0, 0)
        let minX = startX
        let maxX = startX + (this.prefab.width + this.spacingX) * (totalCount - 1)
        return { minPos: cc.v2(minX, pos.y), maxPos: cc.v2(maxX, pos.y) }
    }

    /**
     * 按照x轴大小排序
     * @param isEnd 为true时候强制刷新位置 
     */
    upDateIndexByX(isEnd = false) {
        this.arr.sort(this.sortData)
        let count = this.arr.length;
        for (let i = 0; i < count; i++) {
            let data = this.arr[i]
            if (!isEnd && data.index == i) continue;
            data.index = i
            let pos = this.getItemPos(i, count)
            data.originPos = pos
            if (data.node.getComponent(ItemCtrl).isTouch) {
                continue;
            }
            data.checkPos = pos
            cc.tween(data.node)
                .to(this.moveSpeed, { position: pos })
                .start()
        }
    }

    //获取按照x轴大小
    sortData(a, b) {
        return a.checkPos.x - b.checkPos.x
    }

}

ItemCtrl.ts

import GameCtrl from "./GameCtrl";

const { ccclass, property } = cc._decorator;

@ccclass
export default class ItemCtrl extends cc.Component {
    @property(cc.Label)
    desc: cc.Label = null;
    data: any = {};
    gameCtrl: GameCtrl = null

    private _originPos: cc.Vec2;
    private _startPos: any;
    private oginPos: any;
    isTouch = false;

    start() {
        this.node.zIndex = 0;
        this.oginPos = this.node.position;
        this.regiestNodeEvent(this.node);
    }

    /** 节点注册事件 */
    regiestNodeEvent(node: cc.Node) {
        if (!node) return;
        node.on(cc.Node.EventType.TOUCH_START, this.touchStartEvent, this);
        node.on(cc.Node.EventType.TOUCH_END, this.touchCancel, this);
        node.on(cc.Node.EventType.TOUCH_CANCEL, this.touchCancel, this);
        node.on(cc.Node.EventType.TOUCH_MOVE, this.touchMoveEvent, this);
    }

    /**
     * 传入数据
     * @param data 数据
     * @param index 顺序
     * @param extData 额外数据
     */
    initData(data, gameCtrl) {
        this.data = data;
        this.desc.string = data.id + "";
        this.gameCtrl = gameCtrl
    }


    touchStartEvent(event) {
        if (this.gameCtrl.isAni) return
        this.isTouch = true
        console.log('touch start--------')
        this._originPos = this.node.getPosition();
        this._startPos = event.getLocation();
        this.node.zIndex = 999;
        this.node.opacity = 200;
        this.gameCtrl.getComponent(GameCtrl).touchId = this.data.id
        this.gameCtrl.getComponent(GameCtrl).lastTouchId = this.data.id
    }

    touchMoveEvent(event) {
        let pos = event.getLocation();
        if (!this._startPos) {
            return;
        }
        //控制横轴移动
        let offset_x = pos.x - this._startPos.x;
        let toPosX = this._originPos.x + offset_x;
        let getSidePos = this.gameCtrl.getSidePos()
        if (toPosX < getSidePos.minPos.x) {
            toPosX = getSidePos.minPos.x
        }
        if (toPosX > getSidePos.maxPos.x) {
            toPosX = getSidePos.maxPos.x
        }
        this.node.x = toPosX
        //控制纵轴移动
        // let offset_y = pos.y - this._startPos.y;
        // this.node.y = this._originPos.y + offset_y;

        let isRight = this.node.x > this.data.originPos.x
        let x = isRight ? (this.node.x + this.node.width / 2) : (this.node.x - this.node.width / 2)
        //检测重叠超过1/2,判断为移动
        this.data.checkPos = cc.v2(x, this.data.originPos.y)
        this.gameCtrl.getComponent(GameCtrl).upDateIndexByX()
    }


    touchCancel() {
        this.isTouch = false
        this.gameCtrl.getComponent(GameCtrl).upDateIndexByX(true)
        this.node.opacity = 255;
        this.node.zIndex = 0;
        this.gameCtrl.getComponent(GameCtrl).touchId = null
    }

}

转载自CSDN-专业IT技术社区

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/K86338236/article/details/145551475

评论

赞0

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--