import CollisionDetection from "./CollisionDetection";
import { LQCollideSystem } from "./lq_collide_system/lq_collide_system";
import MapConroler from "./Map";
import { MiniGameSdk } from "./Sdk/MiniGameSdk";

const { ccclass, property } = cc._decorator;
export enum BlockType {
    /*普通地块 */
    "普通块" = 0,
    /*起点地块 */
    "叠加块下" = 1,
    /*湿地 */
    "钥匙块" = 2,
    /*山峰 */
    "上锁块" = 3,
    /*终点地块 */
    "冻结块" = 4,
    /*息壤 */
    "星星块" = 5,
    /*加固 */
    "炸弹块" = 6,
    /*加固 */
    "水平块" = 7,
    /*加固 */
    "垂直块" = 8,
    /*加固 */
    "粘合块" = 9,
    /*加固 */
    "叠加块上" = 10,
    /*障碍块 */
    "障碍块" = 11,

}

export enum BlockColor {

    /*起点地块 */
    "紫色" = 0,
    /*湿地 */
    "黄色" = 1,
    /*山峰 */
    "绿色" = 2,
    /*终点地块 */
    "蓝色" = 3,
    /*息壤 */
    "粉色" = 4,
    /*加固 */
    "橘黄色" = 5,
    /*加固 */
    "青色" = 6,
    /*加固 */
    "白色" = 7,
    /*加固 */
    "红色" = 8,
    /*加固 */
    "灰色" = 9,
    /*障碍块 */
    "无色" = 10,
    /*障碍块 */
    "暗灰色" = 11,
}

export enum PathType {
    err = "err",
    up = "up",
    down = "down",
    left = "left",
    right = "right",
    up_left = "up_left",
    up_right = "up_right",
    down_left = "down_left",
    down_right = "down_right",
    left_up = "left_up",
    left_down = "left_down",
    right_up = "right_up",
    right_down = "right_down",
}
@ccclass
export default class Block extends cc.Component {

    // 新增缓存变量
    private moveInterval = 0; // 约 60 FPS 
    private lastMoveTime = 0;  // 上下两个值来调节跟手，一个是时间轴，一个是距离轴
    private maxSpeed = 300;    //  最大移动距离

    // private otherCollider: cc.Collider = null;
    // @property({
    //     tooltip: '碰撞形状，None就是无敌，不参与碰撞',
    //     type: cc.Enum(BlockType),
    //     // default: BlockType.Nomal,
    //     displayName: '碰撞形状'
    // })

    @property({
        tooltip: '碰撞形状，None就是无敌，不参与碰撞',
        type: cc.Enum(BlockType),
    })
    type: BlockType = BlockType.普通块;

    @property({
        tooltip: '碰撞形状，None就是无敌，不参与碰撞',
        type: cc.Enum(BlockColor),
    })
    color: BlockColor = BlockColor.紫色;

    @property({
        tooltip: '横向长度',
        type: cc.Integer,
    })
    heng: Number = 1;

    @property({
        tooltip: '竖向长度',
        type: cc.Integer,
    })
    shu: Number = 1;

    @property(cc.SpriteAtlas)
    ice_SpriteFrame: cc.SpriteAtlas = null;

    @property(sp.SkeletonData)
    magic_SkeletonData: sp.SkeletonData = null;

    // LIFE-CYCLE CALLBACKS:
    // @property(cc.SpriteAtlas)
    // UI: cc.SpriteAtlas = null;
    private initialTouchOffset: cc.Vec2 = null;
    private offsetTolerance = 100; // 偏移容忍度; 

    allBlocks: any;       //所有的方块,用于计算posX,posY消除
    touchPoint: cc.Vec2 = null;     //触摸点
    isTouch: boolean = false;       //是否触摸
    posX: number = 0;               //地图块的X坐标
    posY: number = 0;               //地图块的Y坐标
    moveLeft: boolean = true;      //是否可以左移;
    moveRight: boolean = true;     //是否可以右移;
    moveUp: boolean = true;        //是否可以上移;
    moveDown: boolean = true;      //是否可以下移;
    moveCorner: number = 0;        //是否碰撞角落
    moveY: number = 0;          //是否可以上下移动;
    moveX: number = 0;          //是否可以左右移动;
    touchPointX: number = 0;        //触摸点X坐标;
    touchPointY: number = 0;        //触摸点Y坐标;
    blockId: number = 0;            //方块ID;
    stacking: cc.Vec2;              //叠加方块
    adhesive: cc.Vec2;              //粘合方块
    level: number = 0;            //叠加方块层数;
    pz: boolean = false;
    over: boolean = false;      //方块是否失效已消失
    collider: any;
    block_Info: any;
    _touchListener: any;
    relative_Position: cc.Vec2;  //点击和方块相对位置
    private _eventManager: any;
    hit: cc.Node;
    otherCollider: any;
    moveStack: boolean;
    touchDelta: cc.Vec2 = cc.v2(0, 0);
    adhesiveNode: any;
    checkCollision: boolean = false;
    //计时器
    private scheduleCallback: any = null;
    private scheduleCallback2: any = null;
    private scheduleCallback3: any = null;
    isEliminatedByHammer: boolean = false; // 标记是否被锤子消除过

    onLoad() {
        this.pz = false;
        this.stacking = cc.v2(0, 0);
        this.adhesive = cc.v2(0, 0);
        this.adhesiveNode = [];
        this.collider = this.node.getComponent(cc.PolygonCollider);
        this.over = false;
        this.checkCollision = false;
    }


    start() {

    }

    jsonDeepClone<T>(obj: T): T {
        return JSON.parse(JSON.stringify(obj));
    }
    //createAd 为是否创建粘合快图片
    init(block_Info, posX, posY, node, createAd) {
        if (block_Info.floor) {
            console.log("floor:", block_Info.floor)
        }
        if (block_Info.floorTime) {
            console.log("floorTime:", block_Info.floorTime)
        }
        this.block_Info = this.jsonDeepClone(block_Info);
        if (node) this.block_Info.node = node;
        this.type = block_Info.type;
        this.color = block_Info.color;
        this.blockId = block_Info.id;
        //console.log("方块类型",this.type,"方块颜色",this.color,"方块ID",this.blockId);
        // if(posX&&posY){
        //     this.posX = posX;
        //     this.posY = posY;
        // }

        // console.log("方块层级",this.node.zIndex);
        this.initColor();
        this.initType();
        this.initBlocks();
        if (this.type != BlockType.叠加块上) {
            this.node.on(cc.Node.EventType.TOUCH_START, this.touchStart, this);
            this.node.on(cc.Node.EventType.TOUCH_MOVE, this.touchMove, this);
            this.node.on(cc.Node.EventType.TOUCH_CANCEL, this.touchEnd, this);
            this.node.on(cc.Node.EventType.TOUCH_END, this.touchEnd, this);
            this.node['_touchListener'].setSwallowTouches(false);
            setTimeout(() => {
                if (this.type == BlockType.粘合块) {
                    // 计算位置偏移
                    const posOffset = cc.v2(
                        this.node.x - this.block_Info.node.x,
                        this.node.y - this.block_Info.node.y
                    );
                    if (createAd) {
                        if (this.node.zIndex >= this.block_Info.node.zIndex)
                            this.createAdhesive();
                        else
                            this.block_Info.node.getComponent("Block").createAdhesive();
                    }
                    const targetNames = ['top', 'down', 'left', 'right'];
                    this.block_Info.node.children.forEach(child => {
                        if (child instanceof cc.Node && targetNames.includes(child.name) && child.getComponent("lq_collide").data_string != "-1") {
                            const clonedChild = cc.instantiate(child);
                            clonedChild.getComponent("lq_collide").data_string = "-1";
                            clonedChild.parent = this.node;
                            // 获取子节点相对于父节点的位置
                            const relativePos = child.getPosition();
                            // 调整子节点位置以保证相对位置不变
                            clonedChild.setPosition(
                                relativePos.x - posOffset.x,
                                relativePos.y - posOffset.y
                            );
                        }
                    });

                    this.adhesive = posOffset;
                }
            }, 100);



            let mapInfo = MapConroler._instance.mapInfo;
            for (let i = 0; i < mapInfo.length; i++) {
                let blockRect = mapInfo[i].getBoundingBox();
                // 使用 cc.Intersection.pointInRect 方法判断点是否在矩形范围内
                let point = cc.v2(this.node.position.x - 5, this.node.position.y + 10)
                if (blockRect.contains(point)) {
                    this.posX = mapInfo[i].getComponent("MapBlock").posX;
                    this.posY = mapInfo[i].getComponent("MapBlock").posY;
                    this.setMapBlock();
                    this.level = 50 + this.posX - this.posY * 3;
                    this.node.zIndex = this.level;
                    this.node.x = mapInfo[i].x + 65;
                    this.node.y = mapInfo[i].y - 60;
                    i = 10000;
                    this.hit = new cc.Node();
                    this.hit.addComponent(cc.Sprite);
                    this.hit.parent = this.node;
                    let name = "xz_" + this.block_Info.block;
                    this.hit.getComponent(cc.Sprite).spriteFrame = this.ice_SpriteFrame._spriteFrames[name];
                    this.hit.setAnchorPoint(this.node.anchorX, this.node.anchorY);
                    this.setHitPosition();
                    // if(this.hit.anchorX == 0.5) this.hit.setPosition(0,-11);
                    // else if(this.hit.anchorX == 0.33) this.hit.setPosition(-13,-11);
                    // else if(this.hit.anchorX == 0.66) this.hit.setPosition(2,-9);
                    // this.hit.opacity = 0;
                    this.hit.active = false;
                    break;
                }
            }
        }

        if (block_Info.floor && block_Info.floorTime) {

        }
    }


    //初始化方块类型
    initType() {
        let posConfig = cc.fx.GameConfig.PROP_INFO[this.block_Info.block];

        switch (this.type) {
            case BlockType.炸弹块:
                let boom = cc.instantiate(MapConroler._instance.Block_Prop[this.type]);
                boom.parent = this.node;
                boom.setPosition(posConfig.pos1.x, posConfig.pos1.y);
                if (this.block_Info?.boomTime)
                    boom.getComponent("Boom").init(this.block_Info.boomTime);
                break;
            case BlockType.星星块:
                let star = cc.instantiate(MapConroler._instance.Block_Prop[this.type]);
                star.anchorX = this.node.anchorX;
                star.anchorY = this.node.anchorY;
                star.getComponent(cc.Sprite).spriteFrame = star.getComponent("Star").star_SpriteFrame.getSpriteFrame("star_" + this.block_Info.block);
                star.parent = this.node;
                star.setPosition(posConfig.pos4.x - 10, posConfig.pos4.y);
            case BlockType.钥匙块:
                let key = cc.instantiate(MapConroler._instance.Block_Prop[this.type]);
                key.parent = this.node;
                key.setPosition(posConfig.pos1.x, posConfig.pos1.y);
                break;
            case BlockType.上锁块:
                let lock = cc.instantiate(MapConroler._instance.Block_Prop[this.type]);
                lock.parent = this.node;
                lock.setPosition(posConfig.pos1.x, posConfig.pos1.y);
                lock.getComponent("Lock").init(this.block_Info.lockTime);
                break;
            case BlockType.冻结块:
                let freeze = cc.instantiate(MapConroler._instance.Block_Prop[this.type]);
                freeze.parent = this.node;
                let name = "ice_" + this.block_Info.block;
                let spriteFrame = this.ice_SpriteFrame._spriteFrames[name];
                freeze.getChildByName("icon").getComponent(cc.Sprite).spriteFrame = spriteFrame;
                let freezeX = posConfig.pos6.x - (this.node.width * (this.node.anchorX - 0.5)); let freezeY = posConfig.pos6.y + this.node.height / 2;
                if (this.block_Info.block == 2) {
                    freeze.setPosition(freezeX + 4, freezeY - 10);
                }
                else freeze.setPosition(freezeX, freezeY);
                freeze.getComponent("Freeze").init(this.block_Info.freezeTime);
                freeze.getChildByName("time").setPosition(posConfig.pos5.x - 10 - freezeX, posConfig.pos5.y - 2 - freezeY);
                break;
            case BlockType.水平块:
                let horizontal = cc.instantiate(MapConroler._instance.Block_Prop[this.type]);
                horizontal.parent = this.node;
                let heng = "heng" + this.heng;
                horizontal.getChildByName(heng).active = true;
                horizontal.setPosition(posConfig.pos2.x - 3, posConfig.pos2.y);
                break;
            case BlockType.垂直块:
                let vertical = cc.instantiate(MapConroler._instance.Block_Prop[this.type]);
                vertical.parent = this.node;
                let shu = "shu" + this.shu;
                vertical.getChildByName(shu).active = true;
                vertical.setPosition(posConfig.pos3.x, posConfig.pos3.y);
                break;
            case BlockType.叠加块上:
                this.moveStack = false;
                this.node.off(cc.Node.EventType.TOUCH_START);
                this.node.off(cc.Node.EventType.TOUCH_MOVE);
                this.node.off(cc.Node.EventType.TOUCH_CANCEL);
                this.node.off(cc.Node.EventType.TOUCH_END);
                // this.selfBoxColliders = [];
                this.node.zIndex = 201;
                let pos = this.getStackingPos();
                this.node.setPosition(this.node.x + pos.x, this.node.y + pos.y);
                this.stacking = cc.v2(this.node.x - this.block_Info.node.x, this.node.y - this.block_Info.node.y);
                this.block_Info.node.getComponent("Block").block_Info.node = this.node;
                this.node.scaleX *= 0.7;
                this.node.scaleY *= 0.7;
                for (let i = 0; i < this.node.children.length; i++) {
                    if (this.node.children[i].name == "left" || this.node.children[i].name == "right" || this.node.children[i].name == "top" || this.node.children[i].name == "down")
                        this.node.children[i].active = false;
                }
                break;
        }
    }

    //初始化方块颜色
    initColor() {
        let name = this.color + "color" + this.block_Info.block;
        let number = Math.floor((this.color - 1) / 2);
        //特殊方块，可移动不可消除类型
        if (this.color == 11) {
            name = "0color" + this.block_Info.block;
            number = 5;
        }
        let blockSpriteFrame = MapConroler._instance.Block_Color[number]._spriteFrames;
        var spriteFrame = blockSpriteFrame[name];
        // if(this.type == BlockType.冻结块){
        //     name = "ice_"+this.block_Info.block;
        //     spriteFrame = this.ice_SpriteFrame._spriteFrames[name];
        // }
        this.node.getChildByName("icon").getComponent(cc.Sprite).spriteFrame = spriteFrame;
    }

    //创建粘合快连接处
    createAdhesive() {
        let box = [];
        for (let i = 0; i < this.allBlocks.length; i++) {
            box.push(cc.v2(this.allBlocks[i].x + this.posX, this.allBlocks[i].y + this.posY));
        }
        let otherBox = [];
        for (let i = 0; i < this.block_Info.node.getComponent("Block").allBlocks.length; i++) {
            otherBox.push(cc.v2(this.block_Info.node.getComponent("Block").allBlocks[i].x + this.block_Info.node.getComponent("Block").posX, this.block_Info.node.getComponent("Block").allBlocks[i].y + this.block_Info.node.getComponent("Block").posY));
        }

        for (let k = 0; k < box.length; k++) {
            for (let j = 0; j < otherBox.length; j++) {
                if ((box[k].x == otherBox[j].x + 1 || box[k].x == otherBox[j].x - 1) && (box[k].y == otherBox[j].y)) {
                    //在X轴 相邻
                    let left = box[k].x == otherBox[j].x + 1 ? "left" : "right";
                    this.addAdhesive(left, box[k]);
                    otherBox.splice(j, 1);
                    j--; // 调整索引
                    if (j < 0) break;
                }
                if ((box[k].y == otherBox[j].y + 1 || box[k].y == otherBox[j].y - 1) && (box[k].x == otherBox[j].x)) {
                    //在Y轴 相邻
                    let down = box[k].y == otherBox[j].y + 1 ? "down" : "up";
                    this.addAdhesive(down, box[k]);
                    otherBox.splice(j, 1);
                    j--; // 调整索引
                    if (j < 0) break;
                }
            }
        }
        // let adhesive = cc.instantiate(MapConroler._instance.Block_Prop[this.type]);
    }

    //具体添加粘合快锁链方法
    addAdhesive(diraction, box) {
        let pos = cc.v2(box.x - this.posX, box.y - this.posY);
        let adhesive = cc.instantiate(MapConroler._instance.Block_Prop[10]);
        adhesive.parent = this.node.parent.getChildByName("Adhesive");
        // adhesive.parent = this.node.getChildByName("adhesive");
        adhesive.setPosition(120 * pos.x - 65 + this.node.x, 120 * pos.y + 60 + this.node.y);
        if (diraction == "left" || diraction == "right") {
            adhesive.getChildByName("heng").active = true;
            adhesive.getChildByName("heng").x = -60;
            if (diraction == "right") adhesive.getChildByName("heng").x = 60;
            adhesive.getChildByName("heng").x += 9;
            adhesive.getChildByName("heng").y += 7;
        }
        else {
            adhesive.getChildByName("shu").active = true;
            adhesive.getChildByName("shu").y = -60;
            if (diraction == "up") adhesive.getChildByName("shu").y = 60;
        }
        adhesive.getComponent("Adhesive").init(this.node);
        this.adhesiveNode.push(adhesive);
    }

    removeAdhesive(action) {
        if (this.adhesiveNode.length > 0) {
            cc.fx.AudioManager._instance.playEffect("adhesive", null);
            for (let i = 0; i < this.adhesiveNode.length; i++) {
                let adhesive = this.adhesiveNode[i];
                // if (action == true)
                //     adhesive.getComponent("Adhesive").remove();
                // else adhesive.destroy();
                adhesive.getComponent("Adhesive").remove();
            }
        }
    }

    //方块落点
    blockFall(point, type) {
        if (this.over == true) return;
        // // 假设 MapConroler 有网格信息，这里简单示例
        const mapWidth = MapConroler._instance.mapWidth;
        const mapHeight = MapConroler._instance.mapHeight;
        const cellSize = 120; // 每个格子的大小，根据实际情况调整

        // 计算点所在的网格坐标
        const gridX = Math.floor((point.x + (mapWidth * cellSize / 2)) / cellSize);
        const gridY = Math.floor((point.y + (mapHeight * cellSize / 2)) / cellSize);

        // 检查网格坐标是否越界
        if (gridX >= 0 && gridX < mapWidth && gridY >= 0 && gridY < mapHeight) {
            const mapBlock = MapConroler._instance.mapBlocksWall[gridX][gridY];
            const blockRect = mapBlock.getBoundingBox();

            // 使用 cc.Intersection.pointInRect 方法判断点是否在矩形范围内
            if (blockRect.contains(point)) {
                //寻找落点
                this.removeMapBlock();
                this.posX = mapBlock.getComponent("MapBlock").posX;
                this.posY = mapBlock.getComponent("MapBlock").posY;
                this.setMapBlock();
                this.level = 50 + this.posX - this.posY * 3;
                this.node.zIndex = this.level;
                //console.log("方块层级", this.node.zIndex);
                this.node.x = mapBlock.x + 65;
                this.node.y = mapBlock.y - 60;

                if (this.type == 9) {
                    if (this.block_Info.node) {
                        this.block_Info.node.x = this.node.x - this.adhesive.x;
                        this.block_Info.node.y = this.node.y - this.adhesive.y;
                    }
                }
                else if (this.type == 1) {
                    this.block_Info.node.getComponent("Block").moveStack = false;
                    this.block_Info.node.x = this.node.x + this.block_Info.node.getComponent("Block").stacking.x;
                    this.block_Info.node.y = this.node.y + this.block_Info.node.getComponent("Block").stacking.y;
                }
            }
        }

        let jg = MapConroler._instance.checkPass(this.node, this.allBlocks);

        if (jg >= 0) {
            // MapConroler._instance.changeRevolvingWall();
            this.over = true;
            this.removeBoxCollider();
            this.removeMapBlock();
            this.removeAction(jg, type);
        }
        else {
            MapConroler._instance.upDoor(this.color);
            this.setVibrate("medium", 1)
            //@ts-ignore
        }

    }
    //移除方块碰撞
    removeBoxCollider() {
        for (let i = 0; i < this.node.children.length; i++) {
            if (this.node.children[i].name == "left" || this.node.children[i].name == "right" || this.node.children[i].name == "top" || this.node.children[i].name == "down"
                || this.node.children[i].name == "tan_up_right" || this.node.children[i].name == "tan_up_left" || this.node.children[i].name == "tan_down_right" || this.node.children[i].name == "tan_down_left"
            )
                this.node.children[i].destroy();
        }
    }
    //移除方块动画
    removeAction(diraction, type) {
        this.node.off(cc.Node.EventType.TOUCH_START);
        this.node.off(cc.Node.EventType.TOUCH_MOVE);
        this.node.off(cc.Node.EventType.TOUCH_CANCEL);
        this.node.off(cc.Node.EventType.TOUCH_END);
        if (diraction == 2 || diraction == 3) {
            // 获取当前节点的宽度和高度
            const currentWidth = this.node.width;
            const currentHeight = this.node.height;
            // 假设将高度增加 50，你可以根据需求修改这个值
            const newHeight = currentHeight + 50;
            // 设置新的节点尺寸
            this.node.setContentSize(currentWidth, newHeight);
        }
        else if (diraction == 0 || diraction == 1) {
            // 获取当前节点的宽度和高度
            const currentWidth = this.node.width;
            const currentHeight = this.node.height;
            // 假设将高度增加 50，你可以根据需求修改这个值
            const newWidth = currentWidth + 50;
            // 设置新的节点尺寸
            this.node.setContentSize(newWidth, currentHeight);
        }
        this.node.addComponent(cc.Mask);
        let self = this;
        let pos = this.node.getPosition();
        if (this.type == BlockType.叠加块下) {
            cc.fx.AudioManager._instance.playEffect("stacking", null);
            let scaleX = this.node.scaleX;
            let scaleY = this.node.scaleY;
            this.block_Info.node.getComponent("Block").restoreNomal(this.posX, this.posY, true);
            cc.tween(this.block_Info.node)
                .to(0.3, { position: pos, scaleX: scaleX > 0 ? 1 : -1, scaleY: scaleY > 0 ? 1 : -1 })
                .start();
        }
        else if (this.type == BlockType.粘合块) {
            this.removeAdhesive(true);
            this.block_Info.node.getComponent("Block").removeAdhesive(true);
            this.block_Info.node.getComponent("Block").restoreNomal(this.block_Info.node.getComponent("Block").posX,
                this.block_Info.node.getComponent("Block").posY, false);
            this.block_Info.node = null;
        }
        else if (this.type == BlockType.星星块) {
            cc.fx.AudioManager._instance.playEffect("starBlock", null);
        }
        else if (this.type == BlockType.炸弹块) {
            this.node.getChildByName("boom").getComponent("Boom").destroyBoom(false);
        }
        else if (this.type == BlockType.钥匙块) {
            cc.fx.AudioManager._instance.playEffect("lockBlock2", null);
        }

        let time = 0.33;
        // this.node.zIndex = 0;
        let width = Math.floor(this.node.width / 120);
        let height = Math.floor(this.node.height / 120);


        setTimeout(() => {
            cc.fx.AudioManager._instance.playEffect("xiaochu", null);
            MapConroler._instance.playHitSound();
        }, 0);
        this.setVibrate("light", 3)

        if (diraction == 0) {
            time = 0.33 * height;
            // time = 0.99;
            for (let i = 0; i < this.node.children.length; i++) {
                cc.tween(this.node.children[i])
                    .to(time, { y: this.node.children[i].y + this.node.children[0].height })
                    .start();
            }
        }
        else if (diraction == 1) {
            time = 0.33 * height;
            // time = 0.99
            for (let i = 0; i < this.node.children.length; i++) {
                cc.tween(this.node.children[i])
                    .to(time, { y: this.node.children[i].y - this.node.children[0].height })
                    .start();
            }
        }
        else if (diraction == 2) {
            time = 0.33 * width;
            // time = 0.99
            for (let i = 0; i < this.node.children.length; i++) {
                cc.tween(this.node.children[i])
                    .to(time, { x: this.node.children[i].x - this.node.children[0].width })
                    .start();
            }
        }
        else if (diraction == 3) {
            time = 0.33 * width
            // time = 0.99
            for (let i = 0; i < this.node.children.length; i++) {
                cc.tween(this.node.children[i])
                    .to(time, { x: this.node.children[i].x + this.node.children[0].width })
                    .start();
            }
        }

        MapConroler._instance.judgeWin(0);

        setTimeout(() => {
            let tempColor = this.color;
            setTimeout(() => {
                MapConroler._instance.upDoor(tempColor);
            }, 250);

            MapConroler._instance.nextLevel(1);
            this.node.active = false;
            this.node.removeFromParent();
            setTimeout(() => {
                if (MapConroler._instance.blockNum != 0 && (MapConroler._instance.openWall.length > 0 ||
                    MapConroler._instance.revolving_state != 0)
                    && !MapConroler._instance.gameOver && !MapConroler._instance.gameWin) {
                    let gameover = MapConroler._instance.predict_End();
                    if (gameover == false) {
                        if (MapConroler._instance.revolving_state == 0)
                            MapConroler._instance.failLevel("lock");
                        else
                            MapConroler._instance.failLevel("rotate");
                    }
                }
            }, 500);

            // this.node.active = false;
            // this.node.removeFromParent();
        }, time * 1000);

    }

    touchStart(event) {
        if (this.over || MapConroler._instance.gameOver) return;
        // 返回世界坐标
        let touchLoc = event.getLocation();
        // https://docs.cocos.com/creator/api/zh/classes/Intersection.html 检测辅助类
        // let pos = this.collider.world.points

        if (!this.collider.world) {
            return;
        }
        // 判断触摸点是否在多边形内
        if (cc.Intersection.pointInPolygon(touchLoc, this.collider.world.points)) {
            if (MapConroler._instance.hammer) {
                // if (this.color == 11) {
                //     MiniGameSdk.API.showToast("不能消除障碍块");
                //     MapConroler._instance.hammerMask.active = false;
                //     MapConroler._instance.hammer = false;
                //     MapConroler._instance.ishammer = false;
                //     let hammerBtn = MapConroler._instance.node.parent.getChildByName("Bottom").getChildByName("destroyBtn");
                //     hammerBtn.getComponent("btnControl").setTouch(true);
                //     return;
                // }
                this.eliminate2();
                this.isTouch = false;
                MapConroler._instance.hammerMask.active = true; //// false
                cc.fx.GameTool.setGray(MapConroler._instance.destroyBtn.node, true)
                MapConroler._instance.destroyBtn.node.getChildByName("mul10").opacity = 0;
                // MapConroler._instance.destroyBtn.getComponent("btnControl").setTouch(false);

                // MapConroler._instance.node.parent.getChildByName("Bottom").getChildByName("destroyBtn").getComponent("btnControl").setTouch(true);
                MapConroler._instance.costHammer();
                MapConroler._instance.usePause();
                MapConroler._instance.node.parent.getChildByName("Mask").active = false;
                return false;
            }
            if (this.type != BlockType.上锁块 && this.type != BlockType.冻结块) {
                MapConroler._instance.startUpdate();
                if (this.type == BlockType.钥匙块)
                    cc.fx.AudioManager._instance.playEffect("lockBlock1", null);
                else
                    cc.fx.AudioManager._instance.playEffect("hit", null);
                this.node.zIndex = 200;
                if (this.type == 9) {
                    if (this.block_Info.node) {
                        this.block_Info.node.zIndex = 200;
                        this.block_Info.node.getComponent("Block").hit.active = true;
                        // this.block_Info.node.getComponent("Block").isTouch = true;
                        MapConroler._instance.downDoor(this.block_Info.node.getComponent("Block").color, this.block_Info.node.getComponent("Block").type);
                        MapConroler._instance.changeRiseFall(this.block_Info.node.getComponent("Block").color, true);
                    }
                }
                else if (this.type == 1) {
                    this.block_Info.node.getComponent("Block").moveStack = true;
                }

                let touchPoint = event.getLocation();
                let local = this.node.parent.convertToNodeSpaceAR(touchPoint);
                this.touchPointX = local.x;
                this.touchPointY = local.y;
                this.moveLeft = this.moveRight = this.moveUp = this.moveDown = true;
                this.isTouch = true;
                this.moveCorner = 0;
                this.relative_Position = cc.v2(this.node.x - local.x, this.node.y - local.y);
                MapConroler._instance.changeRiseFall(this.color, true);
                MapConroler._instance.downDoor(this.color, this.type);
                this.setVibrate("light", 1)
                if (this.hit) this.hit.active = true;
                return true;
            }
            else {
                this.isTouch = false;
                return false;
            }
        }
        else {
            this.isTouch = false;
            return false;
        }

    }

    touchEnd(event) {
        if (MapConroler._instance.gameOver) return;
        if (this.isTouch) {
            this.touchDelta = cc.v2(0, 0);
            this.checkCollision = false;
            MapConroler._instance.changeRiseFall(this.color, false);
            cc.fx.AudioManager._instance.playEffect("down", null);
            MapConroler._instance.removeOneBlock();
            this.isTouch = false;
            this.node.zIndex = this.level;
            this.hit.active = false;
            if (this.type == 9) {
                if (this.block_Info.node) {
                    this.block_Info.node.getComponent("Block").hit.active = false;
                }
            }

            this.touchPoint = event.getLocation();
            let local = cc.v2(this.node.x - 50, this.node.y + 50);
            if (this.type != 10) {
                //@ts-ignore
                this.blockFall(local, true);
                if (this.type == 9) {
                    if (this.block_Info.node) {
                        let localTemp = cc.v2(this.block_Info.node.x - 50, this.block_Info.node.y + 50);
                        this.block_Info.node.getComponent("Block").blockFall(localTemp, false);
                    }
                }
            }
            this.moveLeft = this.moveRight = this.moveUp = this.moveDown = true;
        }


    }

    touchMove(event: cc.Event.EventTouch) {
        if (MapConroler._instance.gameOver) return;

        if (this.isTouch) {
            const delta = event.getDelta();
            const touchPoint = event.getLocation();
            const local = this.node.parent.convertToNodeSpaceAR(touchPoint);
            this.touchPointX = local.x;
            this.touchPointY = local.y;
            delta.x = this.touchPointX - this.node.x + this.relative_Position.x;
            delta.y = this.touchPointY - this.node.y + this.relative_Position.y;

            // 限制移动速度
            this.touchPointX = local.x;
            this.touchPointY = local.y;
            delta.x = this.touchPointX - this.node.x + this.relative_Position.x;
            delta.y = this.touchPointY - this.node.y + this.relative_Position.y;

            // 限制移动速度
            delta.x = Math.max(-this.maxSpeed, Math.min(this.maxSpeed, delta.x));
            delta.y = Math.max(-this.maxSpeed, Math.min(this.maxSpeed, delta.y));

            // 记录触摸移动的增量
            this.touchDelta = delta;
        }
    }

    //超出限制判断
    exceeds(stepx, stepy) {

    }
    //道具魔棒消除
    eliminate(type) {

        clearTimeout(this.scheduleCallback2);
        clearTimeout(this.scheduleCallback);
        clearTimeout(this.scheduleCallback3);
        let self = this;
        //锤子状态消失
        MapConroler._instance.pause = true;

        if (MapConroler._instance.ismagic) {
            this.scheduleCallback = setTimeout(() => {
                this.createLabelsForBlocksWithCustomDelay(0.2)
                if (this.type == BlockType.冻结块) {
                    this.node.getChildByName("freeze").getComponent("Freeze").reduce(2);
                    MapConroler._instance.ismagic = false;
                    return;
                }
                else if (this.type == BlockType.上锁块) {
                    MapConroler._instance.ismagic = false;
                    this.node.getChildByName("lock").getComponent("Lock").reduce();
                    return;
                }
            }, 800);
        }

        if (this.type == BlockType.冻结块 && (!MapConroler._instance.ishammer && !MapConroler._instance.ismagic)) {
            this.node.getChildByName("freeze").getComponent("Freeze").reduce(2);
            return;
        }
        else if (this.type == BlockType.上锁块 && (!MapConroler._instance.ishammer && !MapConroler._instance.ismagic)) {
            this.node.getChildByName("lock").getComponent("Lock").reduce();
            return;
        }

        if (self.type == BlockType.粘合块) {
            self.removeAdhesive(false);
            self.block_Info.node.getComponent("Block").removeAdhesive(false);
            self.block_Info.node.getComponent("Block").restoreNomal(self.block_Info.node.getComponent("Block").posX,
                self.block_Info.node.getComponent("Block").posY, false);
        }
        else if (self.type == BlockType.炸弹块) {
            this.node.getChildByName("boom").getComponent("Boom").stopBoom();
        }
        this.scheduleCallback2 = setTimeout(() => {
            MapConroler._instance.blockNum -= 1;
            MapConroler._instance.special_Treatment(this.node, type);

        }, 950);
        this.scheduleCallback2 = setTimeout(() => {
            //如果方块可以消除
            // MapConroler._instance.blockNum -= 1;
            // MapConroler._instance.special_Treatment(this.node);
            var self = this;
            this.removeMapBlock();
            MapConroler._instance.judgeWin(1);
            let pos = this.node.getPosition();
            if (self.type == BlockType.叠加块下) {
                cc.fx.AudioManager._instance.playEffect("stacking", null);
                let scaleX = self.node.scaleX;
                let scaleY = self.node.scaleY;
                self.block_Info.node.getComponent("Block").restoreNomal(this.posX, this.posY, true);
                cc.tween(self.block_Info.node)
                    .to(0.1, { position: pos, scaleX: scaleX > 0 ? 1 : -1, scaleY: scaleY > 0 ? 1 : -1 })
                    .start();
            }
            else if (self.type == BlockType.炸弹块) {
                this.node.getChildByName("boom").getComponent("Boom").destroyBoom(false);
            }
            else if (this.type == BlockType.星星块) {
                cc.fx.AudioManager._instance.playEffect("starBlock", null);
            }
            else if (this.type == BlockType.钥匙块) {
                cc.fx.AudioManager._instance.playEffect("lockBlock2", null);
            }

            MapConroler._instance.nextLevel(0);
            this.node.active = false;
            this.node.removeFromParent();
            setTimeout(() => {
                if (MapConroler._instance.blockNum != 0 && (MapConroler._instance.openWall.length > 0 ||
                    MapConroler._instance.revolving_state != 0)
                    && !MapConroler._instance.gameOver && !MapConroler._instance.gameWin) {
                    let gameover = MapConroler._instance.predict_End();
                    if (gameover == false) {
                        if (MapConroler._instance.revolving_state == 0)
                            MapConroler._instance.failLevel("lock");
                        else
                            MapConroler._instance.failLevel("rotate");
                    }
                }
            }, 900);
            MapConroler._instance.ismagic = false;

        }, 1350);

    }

    //道具锤子消除
    eliminate2() {
        clearTimeout(this.scheduleCallback2);
        let self = this;
        this.isEliminatedByHammer = true;
        //锤子状态消失
        MapConroler._instance.pause = true;
        if (MapConroler._instance.ishammer == true) {
            let parentSize = this.node.getContentSize();
            setTimeout(() => {
                cc.fx.AudioManager._instance.playEffect("hammer", null);
            }, 300);
            let pos = cc.v3(0, 0, 0)
            if (this.node.anchorX == 1) {
                pos = cc.v3(this.node.position.x - parentSize.width / 2,
                    this.node.position.y + parentSize.height / 2, 0)
            } else if (this.node.anchorX == 0.5) {
                pos = cc.v3(this.node.position.x,
                    this.node.position.y + parentSize.height / 2, 0)
            } else if (this.node.anchorX == 0.33) {
                pos = cc.v3(this.node.position.x + parentSize.width / 4,
                    this.node.position.y + parentSize.height / 2, 0)
            } else if (this.node.anchorX == 0.66) {
                pos = cc.v3(this.node.position.x - parentSize.width / 6,
                    this.node.position.y + parentSize.height / 2, 0)
            }
            //name等于个别
            switch (this.node.name) {
                case "block21":
                    pos = cc.v3(this.node.position.x - parentSize.width / 4,
                        this.node.position.y + parentSize.height / 2, 0)
                    break;
                case "block16":
                    pos = cc.v3(this.node.position.x - parentSize.width / 6,
                        this.node.position.y + parentSize.height / 2, 0)
                case "block10":
                    pos = cc.v3(this.node.position.x - parentSize.width / 4,
                        this.node.position.y + parentSize.height / 2, 0)
                    break;
                case "block8":
                    pos = cc.v3(this.node.position.x - parentSize.width / 6 - parentSize.width / 2,
                        this.node.position.y + parentSize.height / 2, 0)
                    break;
                case "block22":
                    pos = cc.v3(this.node.position.x - parentSize.width / 4,
                        this.node.position.y + parentSize.height - parentSize.height / 4, 0)
                    break;
                case "block20":
                    pos = cc.v3(this.node.position.x - parentSize.height + parentSize.height / 4,
                        this.node.position.y + parentSize.height / 2, 0)
                    break;
                case "block6":
                    pos = cc.v3(this.node.position.x - parentSize.width / 4,
                        this.node.position.y + parentSize.height / 2, 0)
                    break;

            }
            MapConroler._instance.startHammer(pos);
            if (this.type == BlockType.冻结块) {
                MapConroler._instance.ishammer = false;
                if (MapConroler._instance.hammer == true) MapConroler._instance.hammer = false;
                setTimeout(() => {
                    this.node.getChildByName("freeze").getComponent("Freeze").reduce(2);
                }, 1000);

                return;
            }
            else if (this.type == BlockType.上锁块) {
                MapConroler._instance.ishammer = false;
                if (MapConroler._instance.hammer == true) MapConroler._instance.hammer = false;
                setTimeout(() => {
                    this.node.getChildByName("lock").getComponent("Lock").reduce();
                }, 1000);
                return;
            }
        }

        if (this.type == BlockType.冻结块 && (!MapConroler._instance.ishammer && !MapConroler._instance.ismagic)) {
            this.node.getChildByName("freeze").getComponent("Freeze").reduce(2);
            return;
        }
        else if (this.type == BlockType.上锁块 && (!MapConroler._instance.ishammer && !MapConroler._instance.ismagic)) {
            this.node.getChildByName("lock").getComponent("Lock").reduce();
            return;
        }
        if (MapConroler._instance.hammer == true) MapConroler._instance.hammer = false;
        if (self.type == BlockType.粘合块) {
            self.removeAdhesive(false);
            self.block_Info.node.getComponent("Block").removeAdhesive(false);
            self.block_Info.node.getComponent("Block").restoreNomal(self.block_Info.node.getComponent("Block").posX,
                self.block_Info.node.getComponent("Block").posY, false);
        }
        else if (self.type == BlockType.炸弹块) {
            this.node.getChildByName("boom").getComponent("Boom").stopBoom();
        }
        this.scheduleCallback2 = setTimeout(() => {
            //如果方块可以消除
            MapConroler._instance.blockNum -= 1;
            MapConroler._instance.special_Treatment(this.node, true);
            var self = this;
            this.removeMapBlock();
            MapConroler._instance.judgeWin(0);
            let pos = this.node.getPosition();
            if (self.type == BlockType.叠加块下) {
                cc.fx.AudioManager._instance.playEffect("stacking", null);
                let scaleX = self.node.scaleX;
                let scaleY = self.node.scaleY;
                self.block_Info.node.getComponent("Block").restoreNomal(this.posX, this.posY, true);
                cc.tween(self.block_Info.node)
                    .to(0.1, { position: pos, scaleX: scaleX > 0 ? 1 : -1, scaleY: scaleY > 0 ? 1 : -1 })
                    .start();
            }
            else if (self.type == BlockType.炸弹块) {
                this.node.getChildByName("boom").getComponent("Boom").destroyBoom(false);
            }
            else if (this.type == BlockType.星星块) {
                cc.fx.AudioManager._instance.playEffect("starBlock", null);
            }
            else if (this.type == BlockType.钥匙块) {
                cc.fx.AudioManager._instance.playEffect("lockBlock2", null);
            }

            MapConroler._instance.nextLevel(0);
            this.node.active = false;
            this.node.removeFromParent();
            setTimeout(() => {
                if (MapConroler._instance.blockNum != 0 && (MapConroler._instance.openWall.length > 0 ||
                    MapConroler._instance.revolving_state != 0)
                    && !MapConroler._instance.gameOver && !MapConroler._instance.gameWin) {
                    let gameover = MapConroler._instance.predict_End();
                    if (gameover == false) {
                        if (MapConroler._instance.revolving_state == 0)
                            MapConroler._instance.failLevel("lock");
                        else
                            MapConroler._instance.failLevel("rotate");
                    }
                }
            }, 500);
            //如果是锤子状态消除
            MapConroler._instance.ishammer = false;

        }, 900);

    }
    stopTimeCutDown() {
        if (this.scheduleCallback) {
            this.unschedule(this.scheduleCallback);
            this.scheduleCallback = null;
        }
    }
    //震动方法
    setVibrate(type, count) {
        // return;
        // console.log("最新:",cc.fx.GameConfig.GM_INFO.vibrateOpen,type);
        if (!cc.fx.GameConfig.GM_INFO.vibrateOpen) {
            return;
        }
        if (count == 1) {
            //@ts-ignore
            if (typeof wx !== 'undefined' && wx !== null) { // 判断是否在微信环境
                //@ts-ignore
                wx.vibrateShort({
                    type: type,
                    success: () => {
                        // console.log("震动成功1111111111")
                    },
                    fail: (err) => {
                        // console.log("震动失败1111111111",err);
                    }
                });
            } else {
            }
            return;
        }
        let time = 150;
        for (let i = 0; i < 4; i++) {
            setTimeout(() => {
                //@ts-ignore
                if (typeof wx !== 'undefined' && wx !== null) { // 判断是否在微信环境
                    //@ts-ignore
                    wx.vibrateShort({
                        type: type,
                        success: () => {
                            // console.log("震动成功222222222")
                        },
                        fail: (err) => {
                            // console.log("震动失败222222222", err);
                        }
                    });
                } else {
                }
            }, time * i);
        }

    }


    setMoveCorner(diraction) {
        return;
    }

    cmupdate() {
        let cm: any = cc.director.getCollisionManager();
        cm.update();
    }
    //恢复成一般方块
    restoreNomal(posX, posY, type) {
        this.type = 0;
        this.block_Info.node = null;
        this.moveStack = false;
        this.posX = posX;
        this.posY = posY;
        this.setMapBlock();
        this.level = 50 + this.posX - this.posY * 3;
        this.node.zIndex = this.level;
        let j = 1000;
        for (let i = 0; i < this.node.children.length; i++) {
            if (this.node.children[i].name == "New Node") {
                j = i;
            }
            if (i > j) {
                this.node.children[i].active = false;
            }
        }
        if (type) {
            for (let i = 0; i < this.node.children.length; i++) {
                if (this.node.children[i].name == "left" || this.node.children[i].name == "right" || this.node.children[i].name == "top" || this.node.children[i].name == "down")
                    this.node.children[i].active = true;
            }
        }
        this.node.on(cc.Node.EventType.TOUCH_START, this.touchStart, this);
        this.node.on(cc.Node.EventType.TOUCH_MOVE, this.touchMove, this);
        this.node.on(cc.Node.EventType.TOUCH_CANCEL, this.touchEnd, this);
        this.node.on(cc.Node.EventType.TOUCH_END, this.touchEnd, this);
        this.node['_touchListener'].setSwallowTouches(false);
        this.hit = new cc.Node();
        this.hit.addComponent(cc.Sprite);
        this.hit.parent = this.node;
        let name = "xz_" + this.block_Info.block;
        this.hit.getComponent(cc.Sprite).spriteFrame = this.ice_SpriteFrame._spriteFrames[name];
        this.hit.setAnchorPoint(this.node.anchorX, this.node.anchorY);
        this.setHitPosition();
        // if(this.hit.anchorX == 0.5) this.hit.setPosition(0,-11);
        // else if(this.hit.anchorX == 0.33) this.hit.setPosition(-13,-11);
        // else if(this.hit.anchorX == 0.66) this.hit.setPosition(2,-9);
        this.hit.active = false;
    }

    //冻结状态恢复为常规状态
    resetFreeze() {
        this.type = 0;
        this.block_Info.type = 0;
        let name = this.color + "color" + this.block_Info.block;
        let number = Math.floor((this.color - 1) / 2);
        let blockSpriteFrame = MapConroler._instance.Block_Color[number]._spriteFrames;
        var spriteFrame = blockSpriteFrame[name];
        this.node.getChildByName("icon").getComponent(cc.Sprite).spriteFrame = spriteFrame;
    }

    initBlocks() {
        this.allBlocks = [];

        switch (this.block_Info.block) {
            case 0:
                let pos = cc.v2(0, 0);
                this.allBlocks = [pos];
                break;
            case 1:
                let pos1 = cc.v2(0, 0);
                let pos2 = cc.v2(-1, 0);
                this.allBlocks = [pos1, pos2];
                break;
            case 2:
                let pos3 = cc.v2(0, 0);
                let pos4 = cc.v2(0, 1);
                this.allBlocks = [pos3, pos4];
                break;
            case 3:
                let pos5 = cc.v2(0, 0);
                let pos6 = cc.v2(-1, 0);
                let pos7 = cc.v2(-2, 0);
                this.allBlocks = [pos5, pos6, pos7];
                break;
            case 4:
                let pos8 = cc.v2(0, 0);
                let pos9 = cc.v2(0, 1);
                let pos10 = cc.v2(0, 2);
                this.allBlocks = [pos8, pos9, pos10];
                break;
            case 5:
                let pos11 = cc.v2(0, 0);
                let pos12 = cc.v2(-1, 0);
                let pos13 = cc.v2(-1, 1);
                let pos14 = cc.v2(0, 1);
                this.allBlocks = [pos11, pos12, pos13, pos14];
                break;
            case 6:
                let pos15 = cc.v2(0, 0);
                let pos16 = cc.v2(0, 1);
                let pos17 = cc.v2(0, 2);
                let pos18 = cc.v2(-1, 2);
                this.allBlocks = [pos15, pos16, pos17, pos18];
                break;
            case 7:
                let pos19 = cc.v2(0, 0);
                let pos20 = cc.v2(0, 1);
                let pos21 = cc.v2(-1, 1);
                let pos22 = cc.v2(-2, 1);
                this.allBlocks = [pos19, pos20, pos21, pos22];
                break;
            case 8:
                let pos23 = cc.v2(0, 0);
                let pos24 = cc.v2(-1, 0);
                let pos25 = cc.v2(-1, 1);
                let pos26 = cc.v2(-1, 2);
                this.allBlocks = [pos23, pos24, pos25, pos26];
                break;
            case 9:
                let pos27 = cc.v2(0, 0);
                let pos28 = cc.v2(-1, 0);
                let pos29 = cc.v2(-2, 0);
                let pos30 = cc.v2(0, 1);
                this.allBlocks = [pos27, pos28, pos29, pos30];
                break;
            case 10:
                let pos31 = cc.v2(0, 0);
                let pos32 = cc.v2(1, 2);
                let pos33 = cc.v2(0, 1);
                let pos34 = cc.v2(0, 2);
                this.allBlocks = [pos31, pos32, pos33, pos34];
                break;
            case 11:
                let pos35 = cc.v2(0, 0);
                let pos36 = cc.v2(2, 1);
                let pos37 = cc.v2(1, 1);
                let pos38 = cc.v2(0, 1);
                this.allBlocks = [pos35, pos36, pos37, pos38];
                break;
            case 12:
                let pos39 = cc.v2(0, 0);
                let pos40 = cc.v2(0, 1);
                let pos41 = cc.v2(0, 2);
                let pos42 = cc.v2(-1, 0);
                this.allBlocks = [pos39, pos40, pos41, pos42];
                break;
            case 13:
                let pos43 = cc.v2(0, 0);
                let pos44 = cc.v2(-1, 0);
                let pos45 = cc.v2(-2, 0);
                let pos46 = cc.v2(-2, 1);
                this.allBlocks = [pos43, pos44, pos45, pos46];
                break;
            case 14:
                let pos47 = cc.v2(0, 0);
                let pos48 = cc.v2(0, 1);
                let pos49 = cc.v2(-1, 1);
                let pos50 = cc.v2(1, 1);
                this.allBlocks = [pos47, pos48, pos49, pos50];
                break;
            case 15:
                let pos51 = cc.v2(0, 0);
                let pos52 = cc.v2(-1, 0);
                let pos53 = cc.v2(-2, 0);
                let pos54 = cc.v2(-1, 1);
                this.allBlocks = [pos51, pos52, pos53, pos54];
                break;
            case 16:
                let pos55 = cc.v2(0, 0);
                let pos56 = cc.v2(1, 1);
                let pos57 = cc.v2(0, 1);
                let pos58 = cc.v2(0, 2);
                this.allBlocks = [pos55, pos56, pos57, pos58];
                break;
            case 17:
                let pos59 = cc.v2(0, 0);
                let pos60 = cc.v2(0, 1);
                let pos61 = cc.v2(0, 2);
                let pos62 = cc.v2(-1, 1);
                this.allBlocks = [pos59, pos60, pos61, pos62];
                break;
            case 18:
                let pos63 = cc.v2(0, 0);
                let pos64 = cc.v2(0, 1);
                let pos65 = cc.v2(0, 2);
                let pos66 = cc.v2(1, 1);
                let pos67 = cc.v2(-1, 1);
                this.allBlocks = [pos63, pos64, pos65, pos66, pos67];
                break;
            case 19:
                let pos68 = cc.v2(0, 0);
                let pos69 = cc.v2(0, 1);
                let pos70 = cc.v2(-1, 0);
                this.allBlocks = [pos68, pos69, pos70];
                break;
            case 20:
                let pos71 = cc.v2(0, 0);
                let pos72 = cc.v2(-1, 0);
                let pos73 = cc.v2(-1, 1);
                this.allBlocks = [pos71, pos72, pos73];
                break;
            case 21:
                let pos74 = cc.v2(0, 0);
                let pos75 = cc.v2(0, 1);
                let pos76 = cc.v2(1, 1);
                this.allBlocks = [pos74, pos75, pos76];
                break;
            case 22:
                let pos77 = cc.v2(0, 0);
                let pos78 = cc.v2(0, 1);
                let pos79 = cc.v2(-1, 1);
                this.allBlocks = [pos77, pos78, pos79];
                break;
        }
    }

    setMapBlock() {
        if (this.allBlocks.length > 0) {
            for (let i = 0; i < this.allBlocks.length; i++) {
                let pos = this.allBlocks[i];
                let x = this.posX + pos.x;
                let y = this.posY + pos.y;
                MapConroler._instance.mapBlocksWall[x][y].getComponent("MapBlock").block_Id = this.node.uuid;
            }
        }
    }

    removeMapBlock() {
        if (this.posX == 0 && this.posY == 0) {
            return;
        }
        if (this.allBlocks) {
            if (this.allBlocks.length > 0) {
                for (let i = 0; i < this.allBlocks.length; i++) {
                    if (this.allBlocks[i]) {
                        let pos = this.allBlocks[i];
                        let x = this.posX + pos.x;
                        let y = this.posY + pos.y;
                        if (MapConroler._instance.mapBlocksWall[x][y]) {
                            if (MapConroler._instance.mapBlocksWall[x][y].getComponent("MapBlock"))
                                MapConroler._instance.mapBlocksWall[x][y].getComponent("MapBlock").block_Id = "";
                        }
                    }
                }
            }
        }

    }
    //叠加块，位置差异，校准位置
    getStackingPos() {
        switch (this.node.name) {
            case "block0":
                return cc.v2(-21, 22);
            case "block1":
                return cc.v2(-36, 23);
            case "block2":
                return cc.v2(-18, 40);
            case "block3":
                return cc.v2(-59, 25);
            case "block4":
                return cc.v2(-19, 57);
            case "block5":
                return cc.v2(-36, 38);
            case "block6":
                return cc.v2(-19, 97);
            case "block7":
                return cc.v2(-19, 61);
            case "block8":
                return cc.v2(-55, 24);
            case "block9":
                return cc.v2(-20, 24);
            case "block10":
                return cc.v2(-17, 96);
            case "block11":
                return cc.v2(-17, 58);
            case "block12":
                return cc.v2(-20, 24);
            case "block13":
                return cc.v2(-92, 25);
            case "block14":
                return cc.v2(-18, 60);
            case "block15":
                return cc.v2(-58, 24);
            case "block16":
                return cc.v2(-20, 60);
            case "block17":
                return cc.v2(-17, 60);
            case "block18":
                return cc.v2(-17, 60);
            case "block19":
                return cc.v2(-20, 24);
            case "block20":
                return cc.v2(-54, 25);
            case "block21":
                return cc.v2(-17, 60);
            case "block22":
                return cc.v2(-17, 60);
        }
    }

    update(dt: number) {
        if (this.isTouch && this.touchDelta.mag() > 0) {
            //this.moveLeft = this.moveRight = this.moveUp = this.moveDown = true;
            const delta = this.touchDelta;
            const newX = this.node.x + delta.x;
            const newY = this.node.y + delta.y;
            const distance = Math.sqrt(Math.pow(newX - this.node.x, 2) + Math.pow(newY - this.node.y, 2));
            let mag = Math.round(delta.mag());

            // 脱离接触恢复可移动状态
            if (this.moveY === 1) {
                if (this.touchPointY <= this.node.y + this.node.height / 2) {
                    this.moveY = 0;
                }
            } else if (this.moveY === -1) {
                if (this.touchPointY >= this.node.y + this.node.height / 2) {
                    this.moveY = 0;
                }
            }
            if (this.moveX === 1) {
                if (this.touchPointX <= this.node.x - this.node.width / 2) {
                    this.moveX = 0;
                }
                else {
                }
            } else if (this.moveX === -1) {
                if (this.touchPointX >= this.node.x - this.node.width / 2) {
                    this.moveX = 0;
                }
                else {
                }
            }
            //恢复的时候，如果追的距离超过100，则分段移动，避免穿透
            if (distance > 100) {
                mag = 10;
                const speedScale = 0.5;
                delta.x *= speedScale;
                delta.y *= speedScale;
            } else {
                if (mag > 5) {
                    mag = Math.floor(mag / 5);
                }
            }

            // mag = 2;
            const stepx = delta.x / mag;
            const stepy = delta.y / mag;

            for (let index = 0; index < mag; index++) {
                this.moveCorner = 0;
                const tempX = this.node.x + stepx;
                const tempY = this.node.y + stepy;

                if (!this.checkCollision) {
                    if (this.type !== 8 && this.type !== 10) {
                        this.node.x = Math.round(tempX);
                    }
                    if (this.type !== 7 && this.type !== 10) {
                        this.node.y = Math.round(tempY);
                    }
                } else {
                    const isXMain = Math.abs(stepx) > Math.abs(stepy);
                    if (isXMain) {
                        if (this.node.x > tempX) {
                            if (this.moveLeft && this.moveX === 0 && this.type !== 8 && this.type !== 10) {
                                this.node.x = tempX;
                            }
                            if (this.moveX !== 0) {
                                this.moveX = 0;
                            }
                        } else if (this.node.x <= tempX) {
                            if (this.moveRight && this.moveX === 0 && this.type !== 8 && this.type !== 10) {
                                this.node.x = tempX;
                            }
                            if (this.moveX !== 0) {
                                this.moveX = 0;
                            }
                        }

                        if (this.node.y > tempY) {
                            if (this.moveDown && this.moveY === 0 && this.type !== 7 && this.type !== 10) {
                                this.node.y = tempY;
                            }
                            if (this.moveY !== 0) {
                                this.moveY = 0;
                            }
                        } else if (this.node.y <= tempY) {
                            if (this.moveUp && this.moveY === 0 && this.type !== 7 && this.type !== 10) {
                                this.node.y = tempY;
                            }
                            if (this.moveY !== 0) {
                                this.moveY = 0;
                            }
                        }
                    } else {
                        if (this.node.y > tempY) {
                            if (this.moveDown && this.moveY === 0 && this.type !== 7 && this.type !== 10) {
                                this.node.y = tempY;
                            }
                            if (this.moveY !== 0) {
                                this.moveY = 0;
                            }
                        } else if (this.node.y <= tempY) {
                            if (this.moveUp && this.moveY === 0 && this.type !== 7 && this.type !== 10) {
                                this.node.y = tempY;
                            }
                            if (this.moveY !== 0) {
                                this.moveY = 0;
                            }
                        }

                        if (this.node.x > tempX) {
                            if (this.moveLeft && this.moveX === 0 && this.type !== 8 && this.type !== 10) {
                                this.node.x = tempX;
                            }
                            if (this.moveX !== 0) {
                                this.moveX = 0;
                            }
                        } else if (this.node.x <= tempX) {
                            if (this.moveRight && this.moveX === 0 && this.type !== 8 && this.type !== 10) {
                                this.node.x = tempX;
                            }
                            if (this.moveX !== 0) {
                                this.moveX = 0;
                            }
                        }
                    }
                }
                LQCollideSystem.update_logic(dt);
            }
            // 移动完成后重置触摸增量
            this.touchDelta = cc.v2(0, 0);

        }
        if (this.type == BlockType.叠加块下) {
            if (this.block_Info.node != null) {
                if (this.block_Info.node.getComponent("Block").moveStack == true) {
                    this.block_Info.node.x = this.node.x + this.block_Info.node.getComponent("Block").stacking.x;
                    this.block_Info.node.y = this.node.y + this.block_Info.node.getComponent("Block").stacking.y;
                }
            }
        }
        if (this.block_Info) {
            if (this.block_Info.node != null) {
                if (this.type == BlockType.粘合块) {
                    if (this.adhesive.x != 0 && this.adhesive.y != 0 && this.block_Info.node != null) {
                        this.block_Info.node.x = this.node.x - this.adhesive.x;
                        this.block_Info.node.y = this.node.y - this.adhesive.y;
                    }
                    if (this.isTouch == true && this.block_Info.node.getComponent("Block").isTouch == false) {
                        LQCollideSystem.update_logic(dt);
                        this.block_Info.node.x = this.node.x - this.adhesive.x;
                        this.block_Info.node.y = this.node.y - this.adhesive.y;
                    }
                }
            }
        }
    }

    //精细更改 点击高亮位置
    setHitPosition() {
        this.hit.setPosition(13, -16);
        switch (this.block_Info.block) {
            case 0:
                this.hit.setPosition(15, -20);
                break;
            case 1:
                this.hit.setPosition(13, -17.5);
                break;
            case 2:
                this.hit.setPosition(15, -16);
                break;
            case 4:
                this.hit.setPosition(12, -18);
                break;
            case 6:
                this.hit.setPosition(15, -14);
                break;
            case 7:
                this.hit.setPosition(17, -9);
                break;
            case 8:
                this.hit.setPosition(15, -14);
                break;
            case 9:
                this.hit.setPosition(13, -13);
                break;
            case 10:
                this.hit.setPosition(-5.5, -14);
                break;
            case 11:
                this.hit.setPosition(-6, -15);
                break;
            case 12:
                this.hit.setPosition(15, -15);
                break;
            case 13:
                this.hit.setPosition(15, -13);
                break;
            case 13:
                this.hit.setPosition(15, -14);
                break;
            case 14:
                this.hit.setPosition(2, -7);
                break;
            case 15:
                this.hit.setPosition(15, -16);
                break;
            case 16:
                this.hit.setPosition(1, -15.5);
                break;
            case 17:
                this.hit.setPosition(15, -14);
                break;
            case 18:
                this.hit.setPosition(5, -13);
                break;
            case 21:
                this.hit.setPosition(-2, -14);
                break;
            case 22:
                this.hit.setPosition(14, -14);
                break;
        }
    }

    // 边角弹开 避免卡死
    Bounce(name) {
        let distance = 1.5;
        if (name == "tan_down_left") {
            this.node.x = this.node.x + distance;
            this.node.y = this.node.y + distance;
        }
        else if (name == "tan_up_right") {
            this.node.x = this.node.x - distance;
            this.node.y = this.node.y - distance;
        }
        else if (name == "tan_down_right") {
            this.node.x = this.node.x - distance;
            this.node.y = this.node.y + distance;
        }
        else if (name == "tan_up_left") {
            this.node.x = this.node.x + distance;
            this.node.y = this.node.y - distance;
        }
    }

    createSingleBlockEffect(blockPos: any, index: number, blockSize: number, baseOffset: cc.Vec2) {
        const effectNode = new cc.Node(`magic_effect_${index}`);

        const skeletonComponent = effectNode.addComponent(sp.Skeleton);
        if (!this.magic_SkeletonData) {
            console.error("magic_SkeletonData 资源未加载或为空");
            return;
        }
        skeletonComponent.skeletonData = this.magic_SkeletonData;
        skeletonComponent.premultipliedAlpha = false;
        let actualX = blockPos.x * blockSize + baseOffset.x;
        let actualY = blockPos.y * blockSize + baseOffset.y;

        effectNode.setAnchorPoint(0.5, 0.5);

        // 计算在世界坐标系中的位置
        const worldPos = this.node.convertToWorldSpaceAR(cc.v2(actualX - 65, actualY + 70));

        // 获取 Canvas 节点
        const canvas = cc.find('Canvas');
        if (!canvas) {
            console.error("找不到 Canvas 节点");
            return;
        }

        // 将世界坐标转换为 Canvas 的本地坐标
        const canvasPos = canvas.convertToNodeSpaceAR(worldPos);
        effectNode.setPosition(canvasPos);

        // 设置最高层级，确保在所有其他节点之上
        effectNode.zIndex = 9999;

        // 添加到 Canvas 节点下
        MapConroler._instance.node.parent.addChild(effectNode);

        this.playMagicAnimation(skeletonComponent, index);

        // 可选：添加自动清理机制
        this.scheduleOnce(() => {
            if (effectNode && effectNode.isValid) {
                effectNode.removeFromParent();
                effectNode.destroy();
            }
        }, 3); // 3秒后自动清理
    }


    // 播放魔法动画的辅助方法
    playMagicAnimation(skeletonComponent: sp.Skeleton, index: number) {
        try {
            // 检查动画是否存在
            if (!skeletonComponent.findAnimation("play")) {
                // console.error(`动画 "play" 不存在于 Spine 资源中`);
                return;
            }
            skeletonComponent.setAnimation(0, "play", false);
            //播放完自动清理
            // 监听动画完成事件
            skeletonComponent.setCompleteListener((trackEntry, loopCount) => {
                // 动画播放完成后自动清理节点
                if (skeletonComponent.node && skeletonComponent.node.isValid) {
                    // console.log(`第 ${index} 个特效动画播放完成，开始清理节点`);

                    // 移除节点并销毁
                    skeletonComponent.node.removeFromParent();
                    skeletonComponent.node.destroy();
                }
            });

        } catch (error) {
            // console.error(`播放第 ${index} 个方块动画时出错:`, error);
        }
    }

    // 清理
    clearPreviousEffects() {
        const children = this.node.children;
        for (let i = children.length - 1; i >= 0; i--) {
            const child = children[i];
            if (child.name.startsWith('magic_effect_')) {
                child.removeFromParent();
                child.destroy();
            }
        }
    }

    //魔法棒道具使用，动画
    createLabelsForBlocksWithCustomDelay(delayBetweenBlocks: number = 0.1) {
        if (!this.allBlocks || this.allBlocks.length === 0) {
            console.warn("allBlocks 数组为空或未定义");
            return;
        }
        const blockSize = 120;
        const baseOffset = cc.v2(0, 0);
        this.clearPreviousEffects();
        let createOrder = [
            [0],
        ];

        switch (this.node.name) {
            case "block0":
                createOrder = [
                    [0]
                ];
                break;
            case "block1":
                createOrder = [
                    [1],
                    [0]
                ];
                break;
            case "block2":
                createOrder = [
                    [1],
                    [0]
                ];
                break;
            case "block3":
                createOrder = [
                    [1],
                    [0, 2],
                ];
                break;
            case "block4":
                createOrder = [
                    [1],
                    [0, 2]
                ];
                break;
            case "block5":
                createOrder = [
                    [0],
                    [1, 3],
                    [2]
                ];

                break;
            case "block6":
                createOrder = [
                    [2],
                    [1, 3],
                    [0]
                ];
                break;
            case "block7":
                createOrder = [
                    [2],
                    [1, 3],
                    [0]
                ];
                break;
            case "block8":
                createOrder = [
                    [1],
                    [0, 2],
                    [3]
                ];
                break;
            case "block9":
                createOrder = [
                    [0],
                    [1, 3],
                    [2]
                ];
                break;
            case "block10":
                createOrder = [
                    [3],
                    [1, 2],
                    [0]
                ];
                break;
            case "block11":
                createOrder = [
                    [3],
                    [0, 2],
                    [1]
                ];
                break;
            case "block12":
                createOrder = [
                    [0],
                    [1, 3],
                    [2]
                ];
                break;
            case "block13":
                createOrder = [
                    [2],
                    [1, 3],
                    [0]
                ];
                break;
            case "block14":
                createOrder = [
                    [1],
                    [0, 2, 3],
                ];
                break;
            case "block15":
                createOrder = [
                    [1],
                    [0, 2, 3],
                ];
                break;
            case "block16":
                createOrder = [
                    [2],
                    [0, 1, 3],
                ];
                break;
            case "block17":
                createOrder = [
                    [1],
                    [0, 2, 3],
                ];
                break;
            case "block18":
                createOrder = [
                    [1],
                    [0, 2, 3, 4],
                ];
                break;
            case "block19":
                createOrder = [
                    [0],
                    [1, 2],

                ];
                break;
            case "block20":
                createOrder = [
                    [1],
                    [2, 0],

                ];
                break;
            case "block21":
                createOrder = [
                    [1],
                    [2, 0],

                ];
                break;
            case "block22":
                createOrder = [
                    [1],
                    [2, 0],

                ];
                break;
        }
        let currentDelay = 0;
        createOrder.forEach((batch, batchIndex) => {
            batch.forEach(blockIndex => {
                if (blockIndex < this.allBlocks.length) {
                    const blockPos = this.allBlocks[blockIndex];
                    this.scheduleOnce(() => {
                        this.createSingleBlockEffect(blockPos, blockIndex, blockSize, baseOffset);
                    }, currentDelay);
                }
            });
            currentDelay += delayBetweenBlocks;
        });
    }
}


