伪3d拖拽,45度视角,60度视角
工程下载:(待审核)
https://download.csdn.net/download/K86338236/89530812
dragItem2.t s
import mapCreat2 from "./mapCreat2";const { ccclass, property } = cc._decorator;
/*** 拖拽类,挂在要拖拽的节点上*/
@ccclass
export default class dragItem2 extends cc.Component {@property(mapCreat2)mapCreat: mapCreat2 = null;private _originPos: cc.Vec2;private _startPos: any;oginPos: any;colRowPos = cc.v3(0, 0, 0)onLoad() {this.oginPos = this.node.position;this.regiestNodeEvent(this.node.children[0] || this.node);}init(pos) {this.colRowPos = pos;}/** 节点注册事件 */regiestNodeEvent(node: cc.Node) {if (!node) return;node.on(cc.Node.EventType.TOUCH_START, this.touchStartEvent, this);node.on(cc.Node.EventType.TOUCH_MOVE, this.touchMoveEvent, this);node.on(cc.Node.EventType.TOUCH_END, this.touchEndEvent, this);node.on(cc.Node.EventType.TOUCH_CANCEL, this.touchEndEvent, this);}touchStartEvent(event) {console.log('touch start--------')this._originPos = this.node.getPosition();this._startPos = event.getLocation();this.node.zIndex = 9999;this.mapCreat.removeBox(this.colRowPos)}touchMoveEvent(event) {let pos = event.getLocation();if (!this._startPos) {return;}let offset_x = pos.x - this._startPos.x;let offset_y = pos.y - this._startPos.y;this.node.x = this._originPos.x + offset_x;this.node.y = this._originPos.y + offset_y;}touchEndEvent(event) {this._startPos = null;this.setPos(false)}setPos(isInit?) {const { endPos, col, row, layer } = this.mapCreat.getPutPos(this.node, isInit, this.colRowPos)if (!endPos) returnthis.node.position = endPos;this.colRowPos = cc.v3(col, row, layer);this.mapCreat.addBox(cc.v3(col, row, layer))this.node.zIndex = -col * 10 - row * 10 + layer;}
}
mapCreat2.ts
import dragItem from "./dragItem";const { ccclass, property } = cc._decorator;@ccclass
export default class mapCreat extends cc.Component {//可修改mapH = 10; // 地图纵向格子数量mapW = 10; // 地图横向格子数量_layerH = 64.3; // 地图单元格子高度,根据ui素材调整_gridW = 64.3; // 地图单元格子长度,根据ui素材调整_gridH = 19; // 地图单元格子宽度,根据ui素材调整boxAngel = 52;//地图伪3d角度,根据ui素材调整@property(cc.Graphics)map: cc.Graphics = null;@property(cc.Node)boxRoot: cc.Node = null;@property(cc.Node)boxNode: cc.Node = null;maxLayer = 0; //最大高度gridsList = nullonLoad() {this.gridsList = null;this.maxLayer = 0;this.initMap();}protected start(): void {let boxArr = ["1,1|1,2|1,3|2,1|2,2|3,1", "1,1|1,2|2,1", "1,1"]//行列不超过mapW,mapHthis.init(boxArr)}init(boxArr) {this.creatSceneBox(boxArr)}/*** 初始化格子二维数组*/initMap() {this.gridsList = new Array(this.mapW);for (let col = 0; col < this.gridsList.length; col++) {this.gridsList[col] = new Array(this.mapH);}this.map.clear();for (let col = 0; col < this.mapW; col++) {for (let row = 0; row < this.mapH; row++) {this.addGrid(col, row, 0);}}this.drawBlock()}addGrid(x, y, topLayer) {let grid = {x: 0,y: 0,zArr: [0],topLayer: 0}grid.x = x;grid.y = y;grid.topLayer = topLayer;this.gridsList[x][y] = grid;}/*** 绘制底部地图线*/drawBlock() {for (let col = 0; col <= this.mapW; col++) {this.drawLine(cc.v2(col - 0.5, -0.5), cc.v2(col - 0.5, this.mapH - 0.5));}for (let row = 0; row <= this.mapH; row++) {this.drawLine(cc.v2(0 - 0.5, row - 0.5), cc.v2(this.mapW - 0.5, row - 0.5));}}creatSceneBox(boxArr = []) {let maxData = this.getMaxWidth(boxArr)this.boxRoot.children.forEach((value) => { value.active = false })let index = 0;for (let i = 0; i < boxArr.length; i++) {const element = boxArr[i];index = this.creatBox(element, this.boxRoot, i, index, maxData);}}/*** 获取方块位置范围* @param boxArr * @returns */getMaxWidth(boxArr) {let minX = 999let maxX = -999let minZ = 999let maxZ = -999for (let i = 0; i < boxArr.length; i++) {const element1 = boxArr[i];const element = element1.split("|")for (let j = 0; j < element.length; j++) {const element2 = element[j];let pos = element2.split(",")let x = (Number(pos[0]) - 1) || 0let z = (Number(pos[1]) - 1) || 0if (x < minX) minX = xif (x > maxX) maxX = xif (z < minZ) minZ = zif (z > maxZ) maxZ = z}}let middleX = Math.floor((maxX - minX) / 2);let middleY = Math.floor((maxX - minX) / 2);let maxData = { minX, maxX, minZ, maxZ, middleX, middleY }return maxData;}/*** 创建方块初始位置* @param boxString * @param parent * @param layer * @param index * @param maxData * @returns */creatBox(boxString = "", parent: cc.Node, layer, index, maxData) {let boxArr = boxString.split("|")for (let i = 0; i < boxArr.length; i++) {const element = boxArr[i];let colRowPos = element.split(",")let x = Number(colRowPos[0]) - 1 + Math.floor(this.mapW / 2) - maxData.middleXlet y = this.mapH - (Number(colRowPos[1]) + Math.floor(this.mapH / 2)) - maxData.middleYlet box = parent.children[index] || cc.instantiate(this.boxNode)box.parent = parent;let newPos = cc.v3(x, y, layer)let pos = this.getPos(newPos)box.name = `box${pos[0]}_${pos[i]}_layer`box.setPosition(pos)box.zIndex = x * 10 - y * 100 + layer;box.active = truebox.getComponent(dragItem).init(newPos)this.addBox(newPos)index++}return index;}/*** 添加方块到地图数组* @param newPos * @returns */addBox(newPos) {const { x, y, z } = newPos;if (!this.gridsList[x] || !this.gridsList[x][y]) returnlet zArr = this.gridsList[x][y].zArr;if (zArr[z]) return;zArr[z] = 1if (!zArr[z + 1]) zArr[z + 1] = 0if (z + 1 > this.maxLayer) this.maxLayer = z + 1;this.logMap()}/*** 从地图数组移除方块* @param newPos * @returns */removeBox(newPos) {const { x, y } = newPos;if (!this.gridsList[x] || !this.gridsList[x][y]) returnlet zArr = this.gridsList[x][y].zArrzArr[newPos.z] = 0;let newArr = []for (let i = zArr.length - 1; i >= 0; i--) {const element = zArr[i];if (!newArr.length && !element) continue;if (!newArr.length && element) {newArr.unshift(0)}newArr.unshift(element || 0)}if (!newArr.length) {newArr.unshift(0)}this.gridsList[x][y].zArr = newArrthis.gridsList[x][y].topLayer = newArr.lengthif (newArr.length > this.maxLayer) this.maxLayer = newArr.length;this.logMap()}/*** 打印当前方块数组*/logMap() {let str = ""for (let row = this.mapH - 1; row >= 0; row--) {for (let col = 0; col < this.mapW; col++) {for (let i = 0; i <= this.maxLayer; i++) {let box = this.gridsList[col][row].zArr[i] || "0"str += box}str += " "}str += ("\n")}// cc.log(str)}/*** 获取当前位置周围是否有方块* @param pos * @returns */getSideBox(pos) {const { x, y, z } = posif (!this.gridsList[x] || !this.gridsList[y]) return falselet zArr = this.gridsList[x][y].zArrif (zArr[z - 1] || zArr[z + 1]) return truelet chsecArr = [{ x: 0, y: 1 }, { x: 0, y: -1 }, { x: -1, y: 0 }, { x: 1, y: 0 }]let canput = falsefor (let index = 0; index < chsecArr.length; index++) {const element = chsecArr[index];if (!this.gridsList[x + element.x] || !this.gridsList[x + element.x][y + element.y]) {continue;}let zArr = this.gridsList[x + element.x][y + element.y].zArrif (zArr[z]) {canput = true;break;}}return canput;}/*** 根据方块位置,获取需要放置到的位置* @param node * @param isInit * @param colRowPos * @returns */getPutPos(node, isInit = true, colRowPos) {let worldPos = node.convertToWorldSpaceAR(cc.v2(0, 0));let boxPos = this.node.convertToNodeSpaceAR(worldPos);let minDis = 9999;let endPos = boxPos;let endRow = colRowPos.y;let endCol = colRowPos.x;let layer = colRowPos.z;for (let col = 0; col < this.mapW; col++) {for (let row = 0; row < this.mapH; row++) {let data = this.gridsList[col][row]let have = falsefor (let i = 0; i <= this.maxLayer; i++) {const element = data.zArr[i];if (element) have = true}for (let i = 0; i <= this.maxLayer; i++) {const element = data.zArr[i];if (element) continue;if (!isInit && i > 0) {let canPut = this.getSideBox(cc.v3(col, row, i))if (!canPut) continue;}let pos = this.getPos(cc.v3(col, row, i));let distance = pos.sub(boxPos).mag()if (!endPos || distance < minDis) {minDis = distance;endPos = pos;endRow = row;endCol = col;layer = i;}}}}return { endPos, col: endCol, row: endRow, layer }}/*** 根据方块格子下标获取2d坐标* @param pos 方块格子位置 cc.v3(x:列,y:行,z:第几层,最下层为0)* @returns 位置position*/getPos(pos) {const { x, y, z } = poslet radian = (Math.PI / 180 * (this.boxAngel));let posX = (x - this.mapW / 2) * (this._gridW) + y * this._gridH * Math.tan(radian);let posY = (y - this.mapH / 2) * (this._gridH) + z * this._layerH;return cc.v3(posX, posY)}/*** 画线* @param start_col_cow * @param end_col_cow * @param color * @param width */drawLine(start_col_cow, end_col_cow, color = cc.Color.GRAY, width = 2) {this.map.strokeColor = color;this.map.strokeColor.a = 80;//添加透明度let pos1 = this.getPos(start_col_cow)let pos2 = this.getPos(end_col_cow)this.map.lineWidth = width;this.map.moveTo(pos1.x, pos1.y);this.map.lineTo(pos2.x, pos2.y);this.map.stroke();}/*** 画点* @param col * @param row * @param color */drawPoint(col, row, color = new cc.Color().fromHEX("#FF000033")) {this.map.fillColor = color;this.map.fillColor.a = 20;//添加透明度let pos = this.getPos(cc.v2(col, row))this.map.fillRect(pos.x, pos.y, 10, 10);}
}