You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React/JS开发星露谷物语布局工具,求可变网格邻接关系识别最优方案

实现方案

核心改造思路:改用二维数组存储网格状态

完全不需要使用复杂的grid-template-area方案,你提到的数学计算方案只要封装得当一点都不冗余,是当前场景最简洁的实现方式:

  • 首先将原来的一维方块数组改成二维数组存储,每个维度分别对应行、列,每个元素存储当前方块绑定的作物/道具数据,直接通过[行索引][列索引]定位对应方块,相邻方块判断逻辑可以封装成通用工具函数,示例如下:
    // 传入当前坐标,返回上下左右四个方向的有效相邻坐标
    const getNeighbors = (row, col, rowTotal, colTotal) => {
      const directions = [[-1,0], [1,0], [0,-1], [0,1]]
      return directions.filter(([dr, dc]) => {
        const newRow = row + dr
        const newCol = col + dc
        return newRow >=0 && newRow < rowTotal && newCol >=0 && newCol < colTotal
      }).map(([dr, dc]) => [row + dr, col + dc])
    }
    
  • 生成网格的时候直接按行列遍历,给每个CropSquare传入对应的行、列索引,后续所有操作都可以通过行列索引直接定位,不需要靠DOM id或者squareNumber反查位置,修改后的CropGrid示例代码:
    function CropGrid(props) {
      const { numberOfColumns, numberOfRows } = props;
      // 新增网格状态,存储每个格子的绑定数据,初始为空
      const [gridData, setGridData] = useState(() => 
        Array(numberOfRows).fill().map(() => Array(numberOfColumns).fill(null))
      )
    
      // 宽高变化时重新初始化网格
      useEffect(() => {
        setGridData(Array(numberOfRows).fill().map(() => Array(numberOfColumns).fill(null)))
        document.documentElement.style.setProperty('--rows', numberOfRows);
        document.documentElement.style.setProperty('--columns', numberOfColumns);
      }, [numberOfColumns, numberOfRows])
    
      // 格子点击回调
      const handleSquareClick = (row, col) => {
        // 这里写选中作物后更新对应格子数据的逻辑
        // 批量操作时直接调用getNeighbors遍历连续相同数据的格子即可
      }
    
      // 生成网格
      const cropSquares = []
      for(let row = 0; row < numberOfRows; row++) {
        for(let col = 0; col < numberOfColumns; col++) {
          cropSquares.push(
            <CropSquare 
              key={`${row}-${col}`}
              row={row}
              col={col}
              data={gridData[row][col]}
              onClick={() => handleSquareClick(row, col)}
            />
          )
        }
      }
    
      return (
        <div id='crop-grid'>
          {cropSquares}
        </div>
      );
    }
    
  • 连续相同方块批量操作直接用DFS/BFS遍历即可,20*20的网格体量完全不需要考虑性能问题,示例逻辑:
    // 从指定坐标出发,找到所有相邻且数据相同的格子坐标
    const getSameDataBlocks = (startRow, startCol) => {
      const targetData = gridData[startRow][startCol]
      if(targetData === null) return []
      const visited = new Set()
      const result = []
      const queue = [[startRow, startCol]]
      visited.add(`${startRow}-${startCol}`)
      while(queue.length) {
        const [row, col] = queue.shift()
        result.push([row, col])
        getNeighbors(row, col, numberOfRows, numberOfColumns).forEach(([nr, nc]) => {
          const key = `${nr}-${nc}`
          if(!visited.has(key) && gridData[nr][nc] === targetData) {
            visited.add(key)
            queue.push([nr, nc])
          }
        })
      }
      return result
    }
    

第三方库说明

你这个场景不需要额外引入第三方库,目前的CSS Grid实现已经完全满足动态尺寸的需求,常见的网格类库都是面向可拖拽、可调整大小的复杂布局场景,引入后反而会增加不必要的包体积和复杂度。

内容的提问来源于stack exchange,提问作者Marty Smith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 07:06:01