import Gamecfg from "../../common/gameCfg"; import { xlsChapterLayout } from "../../common/xlsConfig"; import UEBase from "../../frameWork/compment/UEBase"; import { GridConstant } from "./GridConstant"; import UECell, { I_CellData } from "./UECell"; import UECube from "./UECube"; const { ccclass, property } = cc._decorator; const DRAG_THRESHOLD: number = 10; // 拖动判定阈值(像素) @ccclass export default class UEGridMap extends UEBase { static readonly BundleKey: string = "gridMap"; static readonly PrefabUrl: string = "UEGridMap"; static readonly CLS: string = "UEGridMap"; @property(cc.Prefab) cellPrefab: cc.Prefab = null!; @property(cc.Prefab) cubePrefab: cc.Prefab = null!; @property(cc.Node) gridLayer: cc.Node = null; @property(cc.Node) cellLayer: cc.Node = null; @property(cc.Node) cubeLayer: cc.Node = null; cellMap: { [gid: number]: UECell } = {}; private isDragging: boolean = false; private dragStartPos: cc.Vec2 = cc.v2(0, 0); private selectedCell: UECell = null!; private clickCnt: number = 0; Init() { this.gridLayer.setContentSize(GridConstant.CELL_WIDTH * GridConstant.ROW, GridConstant.CELL_HEIGHT * GridConstant.COL); this.LoadMapData(); this.InitEvent(); } InitEvent(): void { this.gridLayer.on(cc.Node.EventType.TOUCH_START, this.OnTouchStart, this); this.gridLayer.on(cc.Node.EventType.TOUCH_MOVE, this.OnTouchMove, this); this.gridLayer.on(cc.Node.EventType.TOUCH_END, this.OnTouchEnd, this); this.gridLayer.on(cc.Node.EventType.TOUCH_CANCEL, this.OnTouchEnd, this); } /** 加载地图数据 */ private LoadMapData() { let chapterInfoCfg = Gamecfg.chapterInfo.getItem("1"); let layoutCfg = Gamecfg.chapterLayoutList.getItemList("1"); let layoutGridMap: { [grid: number]: xlsChapterLayout } = {}; layoutCfg.forEach(element => { layoutGridMap[element.grid] = element; }); const startX = -(GridConstant.ROW * GridConstant.CELL_WIDTH) / 2; const startY = (GridConstant.COL * GridConstant.CELL_HEIGHT) / 2; this.cellMap = {}; for (let i = 0; i < GridConstant.COL; i++) { let rowCells = []; let rowCubes = []; for (let j = 0; j < GridConstant.ROW; j++) { let idx = (i + 1) * 10 + (j + 1); if (chapterInfoCfg.grid.indexOf(idx) != -1) { let cell = this.CreateCell(i, j); rowCells.push(cell); let cellCfg: xlsChapterLayout = layoutGridMap[idx]; let cube = null; if (cellCfg) { cube = cc.instantiate(this.cubePrefab).getComponent(UECube); rowCubes.push(cube); this.cubeLayer.addChild(cube.node); cube.node.width = GridConstant.CELL_WIDTH; cube.node.height = GridConstant.CELL_HEIGHT; cube.node.setPosition(cc.v2( startX + j * GridConstant.CELL_WIDTH + GridConstant.CELL_WIDTH / 2, startY - i * GridConstant.CELL_HEIGHT - GridConstant.CELL_HEIGHT / 2 )); cube.Init({ type: cellCfg.type, id: cellCfg.correlationId, zIndex: idx, unlock: cellCfg.unlock }, idx) } cell.Init({ zIndex: idx, ueCube: cube }); this.cellMap[idx] = cell; } } } } /** 创建格子 */ private CreateCell(i: number, j: number) { const startX = -(GridConstant.ROW * GridConstant.CELL_WIDTH) / 2; const startY = (GridConstant.COL * GridConstant.CELL_HEIGHT) / 2; let cell = cc.instantiate(this.cellPrefab).getComponent(UECell); this.cellLayer.addChild(cell.node); cell.node.width = GridConstant.CELL_WIDTH; cell.node.height = GridConstant.CELL_HEIGHT; cell.node.setPosition(cc.v2( startX + j * GridConstant.CELL_WIDTH + GridConstant.CELL_WIDTH / 2, startY - i * GridConstant.CELL_HEIGHT - GridConstant.CELL_HEIGHT / 2 )); return cell; } private OnTouchStart(event: cc.Event.EventTouch): void { const touchPos = this.gridLayer.convertToNodeSpaceAR(event.getLocation()); const cell = this.GetCellByPos(touchPos); if (cell && cell.CanDrag()) { this.dragStartPos = touchPos; if (this.selectedCell && this.selectedCell != cell) { this.selectedCell.SetSelect(false); this.clickCnt = 1; } else if (!this.selectedCell) { this.clickCnt = 1; } this.selectedCell = cell; cell.SetSelect(true); } } private OnTouchMove(event: cc.Event.EventTouch): void { if (!this.selectedCell) return; const touchPos = this.gridLayer.convertToNodeSpaceAR(event.getLocation()); const distance = touchPos.sub(this.dragStartPos).mag(); // 只有当移动距离超过阈值时才开始拖动 if (!this.isDragging && distance >= DRAG_THRESHOLD) { this.isDragging = true; this.selectedCell.GetCube().StartDrag(); this.selectedCell.SetSelect(false); } if (this.isDragging) { // 计算移动差值并应用到cube节点 const deltaPos = touchPos.sub(this.dragStartPos); const cube = this.selectedCell.GetCube(); const originalPos = cube.node.getPosition(); cube.node.setPosition(originalPos.x + deltaPos.x, originalPos.y + deltaPos.y); this.dragStartPos = touchPos; } } private OnTouchEnd(event: cc.Event.EventTouch): void { if (!this.selectedCell) return; const touchPos = this.gridLayer.convertToNodeSpaceAR(event.getLocation()); const targetCell = this.GetCellByPos(touchPos); if (!this.isDragging && this.selectedCell === targetCell) { //二次点击同一个格子 if (!targetCell.IsEmpty()) { targetCell.GetCube().PlayJellyAnim(); if (this.clickCnt >= 2) { console.log("二次点击同一个格子"); } else { this.clickCnt++; } } } else { if (!this.isDragging) return; if (targetCell) { this.TryMergeItems(this.selectedCell, targetCell); this.selectedCell.SetSelect(false); targetCell.SetSelect(true); } else { this.selectedCell.GetCube().BackToOriginalPos(true); } this.isDragging = false; this.selectedCell = targetCell; } } private GetCellByPos(pos: cc.Vec2): UECell | null { const startX = -(GridConstant.ROW * GridConstant.CELL_WIDTH) / 2; const startY = (GridConstant.COL * GridConstant.CELL_HEIGHT) / 2; const row = Math.floor((pos.x - startX) / GridConstant.CELL_WIDTH); const col = Math.floor((startY - pos.y) / GridConstant.CELL_HEIGHT); if (col >= 0 && col < GridConstant.COL && row >= 0 && row < GridConstant.ROW) { let idx = (col + 1) * 10 + (row + 1); return this.cellMap[idx]; } return null; } /** 尝试合成 */ private TryMergeItems(fromCell: UECell, toCell: UECell): void { if (toCell.IsEmpty()) { //格子上没有物品 fromCell.MoveCubeToCell(toCell); toCell.SetCube(fromCell.GetCube()); fromCell.SetCube(null); } else if (this.CanMergeItems(fromCell, toCell)) { toCell.GetCube().PlayMergeAnim(); } else { this.SwitchCell(fromCell, toCell); } } private CanMergeItems(fromCell: UECell, toCell: UECell): boolean { if (fromCell.GetCube().getCubeData().type == toCell.GetCube().getCubeData().type && fromCell.GetCube().getCubeData().id != fromCell.GetCube().getCubeData().id ) { return true; } return false; } private SwitchCell(fromCell: UECell, toCell: UECell): void { //交换格子 let fromCube = fromCell.GetCube(); let toCube = toCell.GetCube(); fromCell.SetCube(toCube); toCell.SetCube(fromCube); toCube.MoveToNewPos(cc.v3(fromCell.node.x, fromCell.node.y)); fromCube.MoveToNewPos(cc.v3(toCell.node.x, toCell.node.y), 0.05); } /** 抛出新的物品 */ private ThrowNewItem() { } }