import CollisionDetection from "./CollisionDetection"; import { LQCollideSystem } from "./lq_collide_system/lq_collide_system"; import MapConroler from "./Map"; const {ccclass, property} = cc._decorator; export enum BlockType{ /*普通地块 */ "普通块" = 0, /*起点地块 */ "叠加块下" = 1, /*湿地 */ "钥匙块" = 2, /*山峰 */ "上锁块" = 3, /*终点地块 */ "冻结块" = 4, /*息壤 */ "星星块" = 5, /*加固 */ "炸弹块" = 6, /*加固 */ "水平块" = 7, /*加固 */ "垂直块" = 8, /*加固 */ "粘合块" = 9, /*加固 */ "叠加块上" = 10, } export enum BlockColor{ /*起点地块 */ "紫色" = 0, /*湿地 */ "黄色" = 1, /*山峰 */ "绿色" = 2, /*终点地块 */ "蓝色" = 3, /*息壤 */ "粉色" = 4, /*加固 */ "橘黄色" = 5, /*加固 */ "青色" = 6, /*加固 */ "白色" = 7, /*加固 */ "红色" = 8, /*加固 */ "灰色" = 9, } 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; // 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; 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(obj: T): T { return JSON.parse(JSON.stringify(obj)); } //createAd 为是否创建粘合快图片 init(block_Info,posX,posY,node,createAd){ 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 0){ for(let i=0; i= 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){ this.over = true; MapConroler._instance.changeState(); this.removeBoxCollider(); this.removeMapBlock(); this.removeAction(jg); } else{ MapConroler._instance.upDoor(this.color); this.setVibrate("medium",1) //@ts-ignore } } removeBoxCollider(){ for(let i=0; i0?1:-1,scaleY:scaleY>0?1:-1}) .start(); } else if(this.type == BlockType.粘合块){ this.removeAdhesive(); this.block_Info.node.getComponent("Block").removeAdhesive(); 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.炸弹块){ this.node.getChildByName("boom").getComponent("Boom").destroyBoom(); } 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); }, 300 ); this.setVibrate("light",3) if(diraction == 0){ time = 0.33*height; // time = 0.99; for(let i=0; i { let tempColor = this.color; setTimeout(() => { MapConroler._instance.upDoor(tempColor); }, 250); MapConroler._instance.nextLevel(); this.node.active = false; this.node.removeFromParent(); // 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){ this.eliminate(); this.isTouch = false; MapConroler._instance.hammerMask.active = false; MapConroler._instance.node.parent.getChildByName("Bottom").getChildByName("destroyBtn").getComponent("btnControl").setTouch(true); return false; } if(this.type != BlockType.上锁块 && this.type != BlockType.冻结块){ MapConroler._instance.startUpdate(); 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; MapConroler._instance.downDoor(this.block_Info.node.getComponent("Block").color,this.block_Info.node.getComponent("Block").type); } } 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.block_Info.node.getComponent("Block").isTouch = 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); 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); } } } this.moveLeft = this.moveRight = this.moveUp = this.moveDown = true; } } touchMove(event: cc.Event.EventTouch) { if(MapConroler._instance.gameOver) return; // const currentTime = Date.now(); // // 如果距离上次移动时间小于间隔时间,直接返回 // if (currentTime - this.lastMoveTime < this.moveInterval) { // return; // } // this.lastMoveTime = currentTime; 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(){ //锤子状态消失 MapConroler._instance.pause = true; MapConroler._instance.hammer = false; //如果方块是有特殊状态,则特殊处理 if(this.type == BlockType.冻结块){ this.node.getChildByName("freeze").getComponent("Freeze").reduce(2); return; } else if(this.type == BlockType.上锁块){ this.node.getChildByName("lock").getComponent("Lock").reduce(); return; } //如果方块可以消除 MapConroler._instance.blockNum -= 1; MapConroler._instance.special_Treatment(this.node); var self = this; this.removeMapBlock(); setTimeout(() => { let pos = this.node.getPosition(); if(self.type == BlockType.叠加块下){ 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.粘合块){ 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").destroyBoom(); } MapConroler._instance.nextLevel(); this.node.active = false; this.node.removeFromParent(); }, 200); } 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 0){ for(let i=0; i 0){ for(let i=0; i 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{ } } 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.叠加块上 && this.moveStack == true){ if(this.stacking.x != 0 || this.stacking.y!= 0){ this.node.x = this.block_Info.node.x + this.stacking.x; this.node.y = this.block_Info.node.y + this.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; } } } } } }