返回

40 行 JS 代码打造你的 2048 游戏:易如反掌!

前端

如何通过 40 行 JavaScript 代码构建一个 2048 游戏:易如反掌!

# 序言

在悠闲的午后,是否想要尝试一些有趣的活动来放松身心?今天,我们向您推荐一款休闲又益智的游戏——2048。只需要几分钟的时间和几行代码,你就可以拥有一款让你沉浸其中的 2048 游戏!准备好了吗?那就让我们开始吧!

# 游戏前置

——了解 2048 ——

2048 是一款益智游戏,由意大利程序员 Gabriele Cirulli 创造,于 2014 年 3 月 9 日发布。它的玩法很简单,但想要精通却很难:你需要通过滑动瓷砖的方式来合并相同数字的瓷砖,最终将它们合并成 2048。

# **快速上手**

——JS 代码实现 ——

接下来,我们就来一步步将 2048 游戏用代码构建出来。

  1. 准备游戏区域
// 创建一个 4x4 的游戏区域
const grid = Array(4).fill(Array(4).fill(0));
  1. 生成随机数字瓷砖
// 随机生成一个 2 或 4 的数字瓷砖
const generateRandomTile = () => {
  const tile = Math.random() < 0.5 ? 2 : 4;
  return tile;
};

// 将随机数字瓷砖添加到游戏区域
const addRandomTile = () => {
  const emptyCells = [];
  for (let i = 0; i < 4; i++) {
    for (let j = 0; j < 4; j++) {
      if (grid[i][j] === 0) {
        emptyCells.push({ i, j });
      }
    }
  }
  if (emptyCells.length > 0) {
    const randomIndex = Math.floor(Math.random() * emptyCells.length);
    const { i, j } = emptyCells[randomIndex];
    grid[i][j] = generateRandomTile();
  }
};
  1. 处理键盘事件,控制移动
// 监听键盘事件
document.addEventListener("keydown", (event) => {
  const direction = event.key;
  moveTiles(direction);
});

// 根据方向移动瓷砖
const moveTiles = (direction) => {
  for (let i = 0; i < 4; i++) {
    for (let j = 0; j < 4; j++) {
      if (grid[i][j] !== 0) {
        moveTile(direction, i, j);
      }
    }
  }
};

// 移动单个瓷砖
const moveTile = (direction, i, j) => {
  const dx = [-1, 0, 1, 0][direction];
  const dy = [0, -1, 0, 1][direction];
  let x = i, y = j;

  // 找到移动方向上的第一个非空瓷砖
  while (x >= 0 && x < 4 && y >= 0 && y < 4 && grid[x][y] === 0) {
    x += dx;
    y += dy;
  }

  // 如果找到了非空瓷砖,并且与当前瓷砖数字相同,则合并两个瓷砖
  if (x >= 0 && x < 4 && y >= 0 && y < 4 && grid[x][y] === grid[i][j]) {
    grid[x][y] += grid[i][j];
    grid[i][j] = 0;
  }

  // 如果没有找到非空瓷砖,则将当前瓷砖移动到该位置
  else if (x >= 0 && x < 4 && y >= 0 && y < 4) {
    grid[x][y] = grid[i][j];
    grid[i][j] = 0;
  }
};
  1. 游戏结束判断
// 检查游戏是否结束
const isGameOver = () => {
  // 检查是否有空单元格
  for (let i = 0; i < 4; i++) {
    for (let j = 0; j < 4; j++) {
      if (grid[i][j] === 0) {
        return false;
      }
    }
  }

  // 检查是否有相邻瓷砖可以合并
  for (let i = 0; i < 4; i++) {
    for (let j = 0; j < 4; j++) {
      if (
        (i < 3 && grid[i][j] === grid[i + 1][j]) ||
        (j < 3 && grid[i][j] === grid[i][j + 1])
      ) {
        return false;
      }
    }
  }

  return true;
};
  1. 游戏胜利判断
// 检查游戏是否胜利
const isGameWin = () => {
  for (let i = 0; i < 4; i++) {
    for (let j = 0; j < 4; j++) {
      if (grid[i][j] === 2048) {
        return true;
      }
    }
  }

  return false;
};
  1. 游戏渲染
// 渲染游戏区域
const renderGrid = () => {
  // 获取游戏区域元素
  const gridElement = document.getElementById("grid");

  // 清空游戏区域
  gridElement.innerHTML = "";

  // 遍历游戏区域并渲染瓷砖
  for (let i = 0; i < 4; i++) {
    for (let j = 0; j < 4; j++) {
      const tile = document.createElement("div");
      tile.classList.add("tile");
      tile.style.left = `${j * 100}px`;
      tile.style.top = `${i * 100}px`;
      tile.textContent = grid[i][j] === 0 ? "" : grid[i][j];
      gridElement.appendChild(tile);
    }
  }
};
  1. 游戏主循环
// 主循环
const gameLoop = () => {
  // 检查游戏是否结束
  if (isGameOver()) {
    alert("游戏结束!");
    return;
  }

  // 检查游戏是否胜利
  if (isGameWin()) {
    alert("你赢了!");
    return;
  }

  // 添加一个随机数字瓷砖
  addRandomTile();

  // 渲染游戏区域
  renderGrid();

  // 请求下一次动画帧
  requestAnimationFrame(gameLoop);
};

// 启动游戏主循环
gameLoop();

就这样,一个完整的 2048 游戏就诞生了!是不是很简单呢?快来亲自尝试一下吧!

# 欢迎互动

如果您对这篇博文有任何疑问或建议,请随时提出。如果您想分享您在构建 2048 游戏时的经验或遇到的一些挑战,也欢迎您与我们互动。期待您的分享!

# 额外资源