构建一个井字棋网页应用

CSSCSSBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

在这个项目中,你将学习如何使用 HTML、CSS 和 JavaScript 创建一个井字棋游戏。井字棋是一款两人游戏,玩家轮流在 3x3 的网格中标记 X 或 O。目标是在水平、垂直或对角线上连续获得三个标记。你将创建必要的 HTML、CSS 和 JavaScript 文件,并逐步实现游戏逻辑。

👀 预览

井字棋游戏预览

🎯 任务

在这个项目中,你将学习:

  • 如何使用 HTML 设置井字棋游戏的基本结构。
  • 如何添加 CSS 样式来定义游戏元素的外观。
  • 如何使用 JavaScript 实现游戏逻辑。
  • 如何处理用户交互、检查胜负或平局,并更新分数。
  • 如何渲染游戏棋盘并更新回合指示器。
  • 如何允许玩家重置游戏并开始新的一轮。

🏆 成果

完成这个项目后,你将能够:

  • 为 Web 应用程序构建 HTML 文件结构。
  • 使用 CSS 类对元素进行样式设置。
  • 使用 JavaScript 实现游戏逻辑。
  • 处理用户交互并相应地更新用户界面。
  • 渲染游戏棋盘并更新回合指示器。
  • 在 JavaScript 中创建事件监听器并处理事件。

创建 HTML 文件

创建一个名为 index.html 的新文件,并向其中添加以下代码。

cd ~/project
touch index.html

这段代码设置了井字棋游戏的基本结构。

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>井字棋</title>
    <link
      href="https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css"
      rel="stylesheet"
    />
    <style>
      /* 游戏的 CSS 样式 */
    </style>
  </head>

  <body>
    <div id="app">
      <h1 class="text-3xl font-bold mb-4 text-gray-900">井字棋</h1>
      <div id="board" class="grid grid-cols-3 gap-4 mb-4">
        <!-- 游戏棋盘单元格 -->
      </div>
      <div id="scoreboard" class="flex justify-between items-center mb-4">
        <!-- 玩家得分 -->
      </div>
      <div
        id="turn-indicator"
        class="text-2xl font-bold mb-4 text-gray-900"
      ></div>
      <button
        id="reset-button"
        class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
      >
        重置游戏
      </button>
    </div>

    <script>
      // 游戏逻辑的 JavaScript 代码
    </script>
  </body>
</html>
✨ 查看解决方案并练习

添加 CSS 样式

在 HTML 文件 <head> 部分的 <style> 标签内,添加游戏所需的 CSS 样式。这些样式定义了游戏元素的外观,如游戏棋盘、单元格、分数和按钮。

<style>
  .board-cell {
    width: 100px;
    height: 100px;
  }

  body {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100vh;
    background-color: #222;
    font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
  }

  #app {
    text-align: center;
    background-color: #f5f5f5;
    border-radius: 8px;
    padding: 24px;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
  }

  h1 {
    font-size: 32px;
    color: #333;
  }

  .text-gray-900 {
    color: #333 !important;
  }

  .text-2xl {
    font-size: 24px;
  }

  .bg-blue-500 {
    background-color: #4267b2;
  }

  .bg-blue-500:hover {
    background-color: #3b5ca0;
  }

  .bg-blue-700 {
    background-color: #385898;
  }

  .text-white {
    color: #fff !important;
  }

  .rounded {
    border-radius: 4px;
  }

  .highlight {
    background-color: #ffed4a;
  }
</style>

你也可以将 style.css 添加到项目中,并使用 <link> 标签将其链接到 HTML 文件。

<link rel="stylesheet" href="style.css" />

选择你喜欢的任何一种方法。

✨ 查看解决方案并练习

添加游戏逻辑 JavaScript 代码

在 HTML 文件末尾的 <script> 标签内,添加处理游戏逻辑的 JavaScript 代码。这段代码跟踪游戏状态、处理用户交互、检查胜负或平局、更新分数并渲染游戏棋盘。

<script>
  // 游戏逻辑代码
</script>
✨ 查看解决方案并练习

初始化游戏变量

在 JavaScript 代码开头声明必要的变量。这些变量将存储游戏状态、玩家分数和其他相关信息。

// 游戏逻辑
const board = ["", "", "", "", "", "", "", "", ""];
let currentPlayer = "X";
let gameEnded = false;
let playerXScore = 0;
let playerOScore = 0;
let winningCells = [];
✨ 查看解决方案并练习

处理单元格点击事件

创建一个名为 handleCellClick 的函数,当游戏棋盘上的某个单元格被点击时,该函数将被调用。此函数将处理主要的游戏逻辑,例如更新棋盘、检查是否获胜、更新分数以及切换当前玩家。

function handleCellClick(index) {
  if (gameEnded || board[index] !== "") return;
  board[index] = currentPlayer;
  renderBoard();

  if (checkWin()) {
    updateScore();
    highlightWinningCells();
    alert(`玩家 ${currentPlayer} 获胜!`);
    gameEnded = true;
  } else if (board.every((cell) => cell !== "")) {
    alert("平局!");
    gameEnded = true;
  } else {
    currentPlayer = currentPlayer === "X" ? "O" : "X";
    updateTurnIndicator();
  }
}
✨ 查看解决方案并练习

检查是否获胜

创建一个名为 checkWin 的函数,用于检查游戏棋盘上是否存在获胜条件。此函数将棋盘数组中的值与获胜组合进行比较,以确定玩家是否赢得了游戏。

function checkWin() {
  const winningCombinations = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6]
  ];

  for (let i = 0; i < winningCombinations.length; i++) {
    const [a, b, c] = winningCombinations[i];
    if (board[a] !== "" && board[a] === board[b] && board[a] === board[c]) {
      winningCells = [a, b, c];
      return true;
    }
  }
  return false;
}
✨ 查看解决方案并练习

重置游戏

创建一个名为 resetGame 的函数,该函数将游戏状态重置为初始值。当点击重置按钮时调用此函数,它会清空棋盘、重置当前玩家、清除获胜单元格、更新轮到谁的指示器并渲染棋盘。

function resetGame() {
  board.fill("");
  currentPlayer = "X";
  gameEnded = false;
  winningCells = [];
  updateTurnIndicator();
  renderBoard();
}
✨ 查看解决方案并练习

更新玩家分数

创建一个名为 updateScore 的函数,用于更新玩家的分数。当玩家赢得一局游戏时调用此函数。它会增加相应玩家的分数,并更新页面上的分数显示。

function updateScore() {
  if (currentPlayer === "X") {
    playerXScore++;
    document.getElementById("player-x-score").textContent = playerXScore;
  } else {
    playerOScore++;
    document.getElementById("player-o-score").textContent = playerOScore;
  }
}
✨ 查看解决方案并练习

更新轮到谁的指示器

创建一个名为 updateTurnIndicator 的函数,该函数会更新页面上的轮到谁的指示器,以显示当前玩家的回合。

function updateTurnIndicator() {
  const turnIndicator = document.getElementById("turn-indicator");
  turnIndicator.textContent = `当前回合:玩家 ${currentPlayer}`;
}
✨ 查看解决方案并练习

突出显示获胜单元格

创建一个名为 highlightWinningCells 的函数,该函数会为游戏棋盘上的获胜单元格添加一个突出显示类。当玩家赢得游戏时调用此函数。

function highlightWinningCells() {
  const cells = document.querySelectorAll(".board-cell");
  cells.forEach((cell, index) => {
    if (winningCells.includes(index)) {
      cell.classList.add("highlight");
    }
  });
}
✨ 查看解决方案并练习

渲染游戏棋盘

创建一个名为 renderBoard 的函数,该函数根据 board 数组的当前状态更新页面上的游戏棋盘。每次玩家移动后都会调用此函数以更新视觉效果。

function renderBoard() {
  const cells = document.querySelectorAll(".board-cell");
  cells.forEach((cell, index) => {
    cell.textContent = board[index];
    cell.classList.remove("highlight");
  });
}
✨ 查看解决方案并练习

添加事件监听器

为游戏棋盘的单元格和重置按钮添加事件监听器。当事件发生时,这些事件监听器会调用相应的函数。

// 事件监听器
const cells = document.querySelectorAll(".board-cell");
cells.forEach((cell, index) => {
  cell.addEventListener("click", () => handleCellClick(index));
});

const resetButton = document.getElementById("reset-button");
resetButton.addEventListener("click", resetGame);
✨ 查看解决方案并练习

初始渲染

在JavaScript代码末尾,添加初始渲染的代码。这段代码设置游戏的初始状态,更新轮到谁的指示器,并渲染游戏棋盘。

// 初始渲染
updateTurnIndicator();
renderBoard();
✨ 查看解决方案并练习

运行项目

现在你可以运行项目并玩井字棋游戏啦!

点击WebIDE右下角的上线按钮来运行项目。

WebIDE上线按钮

这会在Web 8080标签页中打开项目。

Web 8080标签页界面

点击单元格来进行你的回合,然后点击重置按钮开始新游戏。

✨ 查看解决方案并练习

总结

恭喜你!你已经成功使用HTML、CSS和JavaScript创建了一个井字棋游戏。该项目涵盖了创建HTML文件、添加CSS样式、实现游戏逻辑以及处理用户交互。这个游戏允许两名玩家轮流进行,检查是否获胜或平局,更新分数,并突出显示获胜的单元格。现在你可以运行该项目并享受玩井字棋的乐趣啦!

您可能感兴趣的其他 CSS 教程