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

实现拖拽棋子垂直放置功能:基于网格索引的技术问询

实现网格拖拽游戏的垂直放置功能

核心思路落地

你提到的通过**网格索引加减列数(此处为9)**定位上下同列方格的思路完全可行,核心是利用网格索引的连续性(按行顺序排列,每行9个格子),直接通过索引计算快速定位垂直方向的相邻单元格。以下是具体实现步骤和代码示例:


1. 确认网格索引的正确性

确保你的网格单元格索引是按行递增生成的:比如第一行格子索引为0-8,第二行9-17,第三行18-26……这样当前索引 +9就是下一行同列的格子,当前索引 -9就是上一行同列的格子。如果之前的索引生成逻辑有问题,先修正这一步:

const COLUMN_COUNT = 9; // 固定列数,提取为常量方便维护
const ROW_COUNT = 5; // 示例行数

// 生成带正确索引的网格
function generateGrid() {
  const gridContainer = document.getElementById('grid-container');
  let index = 0;
  for (let row = 0; row < ROW_COUNT; row++) {
    const rowEl = document.createElement('div');
    rowEl.classList.add('grid-row');
    for (let col = 0; col < COLUMN_COUNT; col++) {
      const cell = document.createElement('div');
      cell.classList.add('grid-cell');
      cell.dataset.index = index; // 用data属性存储索引,也可直接挂属性
      cell.hasPiece = false; // 标记是否已有棋子
      // 绑定拖拽相关事件
      cell.addEventListener('dragover', (e) => e.preventDefault());
      cell.addEventListener('drop', handleCellDrop);
      rowEl.appendChild(cell);
      index++;
    }
    gridContainer.appendChild(rowEl);
  }
}

2. 改造放置逻辑,支持水平/垂直双方向

第一步:添加方向切换控制(可选,也可通过拖拽方向自动判断)

给用户提供切换放置方向的入口:

<div class="controls">
  <button onclick="setPlacementDir('horizontal')">水平放置</button>
  <button onclick="setPlacementDir('vertical')">垂直放置</button>
</div>
let currentDir = 'horizontal'; // 默认水平放置

function setPlacementDir(dir) {
  currentDir = dir;
}

第二步:编写通用放置函数

替换原来仅支持水平的放置逻辑,加入垂直方向的索引计算:

// 创建红色棋子的工具函数(复用原有逻辑即可)
function createRedPiece() {
  const piece = document.createElement('div');
  piece.classList.add('red-piece');
  piece.draggable = true;
  return piece;
}

// 处理单元格放置事件
function handleCellDrop(e) {
  e.preventDefault();
  const targetCell = e.target.closest('.grid-cell');
  if (!targetCell || targetCell.hasPiece) return; // 目标格子已有棋子,直接返回

  const targetIndex = parseInt(targetCell.dataset.index);
  let validCells = [targetCell];

  // 根据当前方向,获取需要放置棋子的所有单元格
  if (currentDir === 'horizontal') {
    // 水平放置:取右侧相邻格子(以2格棋子为例,可根据需求调整长度)
    const rightIndex = targetIndex + 1;
    const rightCell = document.querySelector(`.grid-cell[data-index="${rightIndex}"]`);
    if (!rightCell || rightCell.hasPiece) return; // 右侧格子不可用,取消放置
    validCells.push(rightCell);
  } else if (currentDir === 'vertical') {
    // 垂直放置:取下侧同列格子(索引+COLUMN_COUNT)
    const bottomIndex = targetIndex + COLUMN_COUNT;
    const bottomCell = document.querySelector(`.grid-cell[data-index="${bottomIndex}"]`);
    // 检查是否超出网格范围(比如最后一行不能向下放置)
    if (!bottomCell || bottomCell.hasPiece) return;
    validCells.push(bottomCell);
  }

  // 给所有有效格子添加棋子并标记状态
  validCells.forEach(cell => {
    cell.appendChild(createRedPiece());
    cell.hasPiece = true;
  });
}

3. 扩展支持多格棋子(可选)

如果你的棋子是3格或更长,只需循环计算索引即可:

// 支持任意长度的垂直放置
function getVerticalValidCells(startIndex, pieceLength) {
  const cells = [];
  for (let i = 0; i < pieceLength; i++) {
    const currentIndex = startIndex + i * COLUMN_COUNT;
    const cell = document.querySelector(`.grid-cell[data-index="${currentIndex}"]`);
    // 只要有一个格子不存在或被占用,就返回null表示不可放置
    if (!cell || cell.hasPiece) return null;
    cells.push(cell);
  }
  return cells;
}

// 在handleCellDrop中调用示例:
// validCells = getVerticalValidCells(targetIndex, 3);
// if (!validCells) return;

关键注意点

  • 边界判断:垂直放置时必须检查计算后的索引是否在网格范围内(比如最后一行的格子,index+9会超出总格子数,此时要禁止放置)
  • 索引一致性:必须保证网格索引是严格按行顺序生成的,否则索引加减列数的逻辑会失效
  • 状态标记:所有放置了棋子的格子要标记hasPiece,避免重复放置

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 19:41:24