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

2048游戏上下方向键触发undefined错误求助(附完整代码)

2048游戏上下方向键触发后显示undefined的问题排查与解决

针对你遇到的左右方向键正常、上下方向键触发后方块显示undefined的问题,核心原因基本集中在垂直方向的行列转换逻辑错误或移动/渲染环节的空值处理疏漏,以下是具体排查点和解决办法:

一、排查行列转置逻辑

2048的上下移动通常依赖数组转置(把列转成行),复用左右移动的逻辑,之后再转置回原结构。如果转置函数的行列索引写反,会导致部分位置未被正确赋值,出现undefined。

错误示例(索引逻辑颠倒):

function transpose(grid) {
  const newGrid = Array(4).fill().map(() => []);
  for (let i = 0; i < 4; i++) {
    for (let j = 0; j < 4; j++) {
      // 错误:将原行的元素直接放入新行,未实现转置
      newGrid[i].push(grid[i][j]);
    }
  }
  return newGrid;
}

正确转置实现:

function transpose(grid) {
  const newGrid = Array(4).fill().map(() => Array(4).fill(0));
  for (let i = 0; i < 4; i++) {
    for (let j = 0; j < 4; j++) {
      // 行列索引互换,实现矩阵转置
      newGrid[j][i] = grid[i][j];
    }
  }
  return newGrid;
}

二、检查移动函数的元素补全逻辑

左右移动时,会过滤空元素(0)、合并相同值后补0到4个元素,但如果上下移动时转置后的数组未被正确补全,转置回原结构后会出现数组长度不足,导致undefined。

正确的左移函数(可复用为上下移动的基础逻辑):

function moveLeft(row) {
  // 过滤所有空值(0)
  let filteredRow = row.filter(num => num !== 0);
  // 合并相邻相同元素
  for (let i = 0; i < filteredRow.length - 1; i++) {
    if (filteredRow[i] === filteredRow[i + 1]) {
      filteredRow[i] *= 2;
      filteredRow[i + 1] = 0;
    }
  }
  // 再次过滤合并产生的空值,补0至4个元素
  filteredRow = filteredRow.filter(num => num !== 0);
  while (filteredRow.length < 4) {
    filteredRow.push(0);
  }
  return filteredRow;
}

上下移动的正确调用逻辑:

function moveUp(grid) {
  // 转置后复用左移逻辑,再转置回原结构
  let transposed = transpose(grid);
  transposed = transposed.map(row => moveLeft(row));
  return transpose(transposed);
}

function moveDown(grid) {
  // 转置后复用右移逻辑,再转置回原结构
  let transposed = transpose(grid);
  transposed = transposed.map(row => moveRight(row));
  return transpose(transposed);
}

三、修复渲染环节的空值处理

如果网格数组中存在undefined或0,直接渲染会显示undefined,需在渲染时判断:0值对应空方块,非0值显示数字,避免undefined暴露。

正确的渲染逻辑:

function renderGrid(grid) {
  const tiles = document.querySelectorAll('.tile');
  tiles.forEach((tile, index) => {
    const row = Math.floor(index / 4);
    const col = index % 4;
    const value = grid[row][col];
    // 仅当value不为0时显示数字,否则清空内容
    tile.textContent = value !== 0 ? String(value) : '';
    // 其他样式处理(如背景色)...
  });
}

四、调试定位问题的技巧

在上下移动的事件处理函数中添加日志,输出移动前后的网格状态,快速定位问题环节:

document.addEventListener('keydown', (e) => {
  let newGrid = [...grid.map(row => [...row])];
  if (e.key === 'ArrowUp') {
    newGrid = moveUp(newGrid);
    // 输出转置、移动、转置后的数组状态
    console.log('上移后网格:', newGrid);
  }
  // 其他方向键逻辑...
  if (JSON.stringify(newGrid) !== JSON.stringify(grid)) {
    grid = newGrid;
    renderGrid(grid);
    spawnNewTile();
  }
});

通过日志查看数组中是否存在undefined,若转置后出现,说明转置函数有问题;若移动后出现,说明移动函数的补全逻辑错误;若渲染时出现,说明渲染函数未处理空值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 17:15:20