Kaynağa Gözat

解决拖拽速度快放置

181404010226 6 ay önce
ebeveyn
işleme
d5bc880486
1 değiştirilmiş dosya ile 144 ekleme ve 108 silme
  1. 144 108
      assets/scripts/BlockManager.ts

+ 144 - 108
assets/scripts/BlockManager.ts

@@ -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;
+    }
 }