|
|
@@ -305,111 +305,6 @@ export class BlockManager extends Component {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
- // 尝试将方块放置到网格中
|
|
|
- tryPlaceBlockToGrid(block: Node): boolean {
|
|
|
- if (!this.gridContainer || !this.gridInitialized) return false;
|
|
|
-
|
|
|
- // 获取方块信息
|
|
|
- const blockTransform = block.getComponent(UITransform);
|
|
|
- console.log(`方块 ${block.name} 信息 - 大小: ${blockTransform.width}x${blockTransform.height}, 锚点: (${blockTransform.anchorX}, ${blockTransform.anchorY})`);
|
|
|
-
|
|
|
- // 获取B1节点(在这个情况下,B1就是block自身,因为预制体的根节点就是B1)
|
|
|
- // 如果B1不是根节点,而是子节点,则需要查找B1节点
|
|
|
- let b1Node = block;
|
|
|
- if (block.name !== 'B1') {
|
|
|
- // 查找B1节点
|
|
|
- b1Node = block.getChildByName('B1');
|
|
|
- if (!b1Node) {
|
|
|
- console.error(`找不到B1节点,无法放置方块`);
|
|
|
- return false;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- console.log(`B1节点名称: ${b1Node.name}`);
|
|
|
-
|
|
|
- // 获取方块B1节点在世界坐标中的位置
|
|
|
- const b1WorldPos = b1Node.parent.getComponent(UITransform).convertToWorldSpaceAR(b1Node.position);
|
|
|
- console.log(`放置前 - B1节点世界坐标: (${b1WorldPos.x}, ${b1WorldPos.y})`);
|
|
|
-
|
|
|
- // 将B1节点的世界坐标转换为GridContainer的本地坐标
|
|
|
- const gridPos = this.gridContainer.getComponent(UITransform).convertToNodeSpaceAR(b1WorldPos);
|
|
|
-
|
|
|
- // 检查是否在GridContainer范围内
|
|
|
- const gridSize = this.gridContainer.getComponent(UITransform).contentSize;
|
|
|
- const halfWidth = gridSize.width / 2;
|
|
|
- const halfHeight = gridSize.height / 2;
|
|
|
-
|
|
|
- if (gridPos.x < -halfWidth || gridPos.x > halfWidth ||
|
|
|
- gridPos.y < -halfHeight || gridPos.y > halfHeight) {
|
|
|
- console.log('方块不在GridContainer范围内');
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- // 找到最近的网格节点
|
|
|
- const nearestGrid = this.findNearestGridNode(gridPos);
|
|
|
- if (!nearestGrid) {
|
|
|
- console.log('找不到合适的网格节点');
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- // 获取网格节点信息
|
|
|
- const gridTransform = nearestGrid.getComponent(UITransform);
|
|
|
- console.log(`网格节点 ${nearestGrid.name} 信息 - 大小: ${gridTransform.width}x${gridTransform.height}, 锚点: (${gridTransform.anchorX}, ${gridTransform.anchorY})`);
|
|
|
-
|
|
|
- // 获取网格节点的中心点世界坐标
|
|
|
- const gridCenterWorldPos = this.gridContainer.getComponent(UITransform).convertToWorldSpaceAR(nearestGrid.position);
|
|
|
- console.log(`最近网格节点 ${nearestGrid.name} 中心点世界坐标: (${gridCenterWorldPos.x}, ${gridCenterWorldPos.y})`);
|
|
|
-
|
|
|
- // 检查方块的所有部分是否会与已占用的格子重叠
|
|
|
- if (!this.canPlaceBlockAt(block, nearestGrid)) {
|
|
|
- console.log('方块放置位置已被占用或超出边界');
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- // 计算B1节点应该移动到的位置
|
|
|
- const targetWorldPos = gridCenterWorldPos.clone();
|
|
|
-
|
|
|
- // 计算根节点需要移动的位置
|
|
|
- // 1. 先计算B1节点相对于根节点的偏移
|
|
|
- const b1LocalPos = b1Node.position.clone();
|
|
|
- console.log(`B1节点相对于根节点的偏移: (${b1LocalPos.x}, ${b1LocalPos.y}, ${b1LocalPos.z})`);
|
|
|
-
|
|
|
- // 2. 计算根节点的目标世界坐标
|
|
|
- // 如果B1是根节点,则直接使用网格中心点
|
|
|
- let rootTargetWorldPos;
|
|
|
- if (b1Node === block) {
|
|
|
- rootTargetWorldPos = targetWorldPos.clone();
|
|
|
- } else {
|
|
|
- // 如果B1是子节点,需要计算根节点应该在的位置,使B1对准网格中心
|
|
|
- // 根节点位置 = 网格中心位置 - B1相对于根节点的偏移
|
|
|
- rootTargetWorldPos = new Vec3(
|
|
|
- targetWorldPos.x - b1LocalPos.x,
|
|
|
- targetWorldPos.y - b1LocalPos.y,
|
|
|
- targetWorldPos.z
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- // 3. 将世界坐标转换为根节点父节点的本地坐标
|
|
|
- const rootTargetLocalPos = block.parent.getComponent(UITransform).convertToNodeSpaceAR(rootTargetWorldPos);
|
|
|
-
|
|
|
- // 设置方块位置,确保B1节点的中心与网格节点的中心对齐
|
|
|
- block.position = rootTargetLocalPos;
|
|
|
-
|
|
|
- // 输出放置后B1节点的世界坐标
|
|
|
- const placedB1WorldPos = b1Node.parent.getComponent(UITransform).convertToWorldSpaceAR(b1Node.position);
|
|
|
- console.log(`放置后 - B1节点世界坐标: (${placedB1WorldPos.x}, ${placedB1WorldPos.y})`);
|
|
|
-
|
|
|
- // 输出对比信息,查看是否完全对齐
|
|
|
- console.log(`对齐检查 - 网格中心点: (${gridCenterWorldPos.x}, ${gridCenterWorldPos.y}), B1节点中心点: (${placedB1WorldPos.x}, ${placedB1WorldPos.y})`);
|
|
|
- console.log(`对齐差值 - X: ${placedB1WorldPos.x - gridCenterWorldPos.x}, Y: ${placedB1WorldPos.y - gridCenterWorldPos.y}`);
|
|
|
-
|
|
|
- // 标记占用的格子
|
|
|
- this.markOccupiedPositions(block, nearestGrid);
|
|
|
-
|
|
|
- console.log('方块放置成功');
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
// 找到最近的网格节点
|
|
|
findNearestGridNode(position: Vec3): Node {
|
|
|
if (!this.gridContainer || !this.gridInitialized) return null;
|
|
|
@@ -431,9 +326,15 @@ export class BlockManager extends Component {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // 如果距离太远,不吸附
|
|
|
- if (minDistance > this.gridSpacing / 2) {
|
|
|
- return null;
|
|
|
+ // 增加容错性,放宽距离限制
|
|
|
+ // 如果距离太远,但我们仍然有一个最近的节点,就使用它
|
|
|
+ // 只有在极端情况下才返回null
|
|
|
+ if (minDistance > this.gridSpacing * 2) {
|
|
|
+ console.log(`警告: 距离最近的网格节点 ${nearestNode ? nearestNode.name : '无'} 距离较远: ${minDistance}`);
|
|
|
+ // 如果距离超过网格间距的4倍,可能是完全偏离了网格区域
|
|
|
+ if (minDistance > this.gridSpacing * 4) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
return nearestNode;
|
|
|
@@ -663,4 +564,139 @@ export class BlockManager extends Component {
|
|
|
// 打印网格占用情况
|
|
|
this.printGridOccupation();
|
|
|
}
|
|
|
+
|
|
|
+ // 尝试将方块放置到网格中
|
|
|
+ tryPlaceBlockToGrid(block: Node): boolean {
|
|
|
+ if (!this.gridContainer || !this.gridInitialized) return false;
|
|
|
+
|
|
|
+ // 获取方块信息
|
|
|
+ const blockTransform = block.getComponent(UITransform);
|
|
|
+ console.log(`方块 ${block.name} 信息 - 大小: ${blockTransform.width}x${blockTransform.height}, 锚点: (${blockTransform.anchorX}, ${blockTransform.anchorY})`);
|
|
|
+
|
|
|
+ // 获取B1节点(在这个情况下,B1就是block自身,因为预制体的根节点就是B1)
|
|
|
+ // 如果B1不是根节点,而是子节点,则需要查找B1节点
|
|
|
+ let b1Node = block;
|
|
|
+ if (block.name !== 'B1') {
|
|
|
+ // 查找B1节点
|
|
|
+ b1Node = block.getChildByName('B1');
|
|
|
+ if (!b1Node) {
|
|
|
+ console.error(`找不到B1节点,无法放置方块`);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ console.log(`B1节点名称: ${b1Node.name}`);
|
|
|
+
|
|
|
+ // 获取方块B1节点在世界坐标中的位置
|
|
|
+ const b1WorldPos = b1Node.parent.getComponent(UITransform).convertToWorldSpaceAR(b1Node.position);
|
|
|
+ console.log(`放置前 - B1节点世界坐标: (${b1WorldPos.x}, ${b1WorldPos.y})`);
|
|
|
+
|
|
|
+ // 将B1节点的世界坐标转换为GridContainer的本地坐标
|
|
|
+ const gridPos = this.gridContainer.getComponent(UITransform).convertToNodeSpaceAR(b1WorldPos);
|
|
|
+
|
|
|
+ // 检查是否在GridContainer范围内
|
|
|
+ const gridSize = this.gridContainer.getComponent(UITransform).contentSize;
|
|
|
+ const halfWidth = gridSize.width / 2;
|
|
|
+ const halfHeight = gridSize.height / 2;
|
|
|
+
|
|
|
+ // 增加容错性,放宽边界检查
|
|
|
+ const tolerance = this.gridSpacing * 0.5;
|
|
|
+ if (gridPos.x < -halfWidth - tolerance || gridPos.x > halfWidth + tolerance ||
|
|
|
+ gridPos.y < -halfHeight - tolerance || gridPos.y > halfHeight + tolerance) {
|
|
|
+ console.log('方块不在GridContainer范围内');
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 找到最近的网格节点
|
|
|
+ const nearestGrid = this.findNearestGridNode(gridPos);
|
|
|
+ if (!nearestGrid) {
|
|
|
+ console.log('找不到合适的网格节点');
|
|
|
+ // 尝试使用网格行列直接定位
|
|
|
+ const row = Math.floor((gridPos.y + halfHeight) / this.gridSpacing);
|
|
|
+ const col = Math.floor((gridPos.x + halfWidth) / this.gridSpacing);
|
|
|
+
|
|
|
+ // 检查计算出的行列是否在有效范围内
|
|
|
+ if (row >= 0 && row < this.GRID_ROWS && col >= 0 && col < this.GRID_COLS) {
|
|
|
+ const grid = this.gridNodes[row][col];
|
|
|
+ if (grid) {
|
|
|
+ console.log(`尝试使用计算的行列 (${row}, ${col}) 找到网格节点 ${grid.name}`);
|
|
|
+ return this.tryPlaceBlockToSpecificGrid(block, grid);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ return this.tryPlaceBlockToSpecificGrid(block, nearestGrid);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 尝试将方块放置到指定的网格节点
|
|
|
+ tryPlaceBlockToSpecificGrid(block: Node, targetGrid: Node): boolean {
|
|
|
+ // 获取B1节点
|
|
|
+ let b1Node = block;
|
|
|
+ if (block.name !== 'B1') {
|
|
|
+ b1Node = block.getChildByName('B1');
|
|
|
+ if (!b1Node) {
|
|
|
+ console.error(`找不到B1节点,无法放置方块`);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取网格节点信息
|
|
|
+ const gridTransform = targetGrid.getComponent(UITransform);
|
|
|
+ console.log(`网格节点 ${targetGrid.name} 信息 - 大小: ${gridTransform.width}x${gridTransform.height}, 锚点: (${gridTransform.anchorX}, ${gridTransform.anchorY})`);
|
|
|
+
|
|
|
+ // 获取网格节点的中心点世界坐标
|
|
|
+ const gridCenterWorldPos = this.gridContainer.getComponent(UITransform).convertToWorldSpaceAR(targetGrid.position);
|
|
|
+ console.log(`最近网格节点 ${targetGrid.name} 中心点世界坐标: (${gridCenterWorldPos.x}, ${gridCenterWorldPos.y})`);
|
|
|
+
|
|
|
+ // 检查方块的所有部分是否会与已占用的格子重叠
|
|
|
+ if (!this.canPlaceBlockAt(block, targetGrid)) {
|
|
|
+ console.log('方块放置位置已被占用或超出边界');
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算B1节点应该移动到的位置
|
|
|
+ const targetWorldPos = gridCenterWorldPos.clone();
|
|
|
+
|
|
|
+ // 计算根节点需要移动的位置
|
|
|
+ // 1. 先计算B1节点相对于根节点的偏移
|
|
|
+ const b1LocalPos = b1Node.position.clone();
|
|
|
+ console.log(`B1节点相对于根节点的偏移: (${b1LocalPos.x}, ${b1LocalPos.y}, ${b1LocalPos.z})`);
|
|
|
+
|
|
|
+ // 2. 计算根节点的目标世界坐标
|
|
|
+ // 如果B1是根节点,则直接使用网格中心点
|
|
|
+ let rootTargetWorldPos;
|
|
|
+ if (b1Node === block) {
|
|
|
+ rootTargetWorldPos = targetWorldPos.clone();
|
|
|
+ } else {
|
|
|
+ // 如果B1是子节点,需要计算根节点应该在的位置,使B1对准网格中心
|
|
|
+ // 根节点位置 = 网格中心位置 - B1相对于根节点的偏移
|
|
|
+ rootTargetWorldPos = new Vec3(
|
|
|
+ targetWorldPos.x - b1LocalPos.x,
|
|
|
+ targetWorldPos.y - b1LocalPos.y,
|
|
|
+ targetWorldPos.z
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 将世界坐标转换为根节点父节点的本地坐标
|
|
|
+ const rootTargetLocalPos = block.parent.getComponent(UITransform).convertToNodeSpaceAR(rootTargetWorldPos);
|
|
|
+
|
|
|
+ // 设置方块位置,确保B1节点的中心与网格节点的中心对齐
|
|
|
+ block.position = rootTargetLocalPos;
|
|
|
+
|
|
|
+ // 输出放置后B1节点的世界坐标
|
|
|
+ const placedB1WorldPos = b1Node.parent.getComponent(UITransform).convertToWorldSpaceAR(b1Node.position);
|
|
|
+ console.log(`放置后 - B1节点世界坐标: (${placedB1WorldPos.x}, ${placedB1WorldPos.y})`);
|
|
|
+
|
|
|
+ // 输出对比信息,查看是否完全对齐
|
|
|
+ console.log(`对齐检查 - 网格中心点: (${gridCenterWorldPos.x}, ${gridCenterWorldPos.y}), B1节点中心点: (${placedB1WorldPos.x}, ${placedB1WorldPos.y})`);
|
|
|
+ console.log(`对齐差值 - X: ${placedB1WorldPos.x - gridCenterWorldPos.x}, Y: ${placedB1WorldPos.y - gridCenterWorldPos.y}`);
|
|
|
+
|
|
|
+ // 标记占用的格子
|
|
|
+ this.markOccupiedPositions(block, targetGrid);
|
|
|
+
|
|
|
+ console.log('方块放置成功');
|
|
|
+ return true;
|
|
|
+ }
|
|
|
}
|