使用 HTML、CSS、JavaScript 创建一个简单的井字游戏(02)

简介: 使用 HTML、CSS、JavaScript 创建一个简单的井字游戏

现在我们将编写一些实用函数。在isValidAction函数中,我们将决定用户是否想要执行有效的操作。如果 tile 的内部文本是XorO我们返回 false 作为操作无效,否则 tile 为空所以操作有效。


const isValidAction = (tile) => {
    if (tile.innerText === 'X' || tile.innerText === 'O'){
        return false;
    }
    return true;
};

下一个效用函数将非常简单。在这个函数中,我们将接收一个索引作为参数,并将棋盘数组中的相应元素设置为我们当前玩家的符号。


const updateBoard =  (index) => {
   board[index] = currentPlayer;
}

我们将编写一个小函数来处理玩家的变化。在这个函数中,我们将首先从playerDisplay. 字符串模板文字player${currentPlayer}将成为playerX或playerO取决于当前玩家。接下来,我们将使用三元表达式来更改当前玩家的值。如果是X,它将是O否则它将是X。现在,我们改变了我们用户的价值,我们需要更新innerText的playerDisplay,并应用新的播放器类的。


const changePlayer = () => {
    playerDisplay.classList.remove(`player${currentPlayer}`);
    currentPlayer = currentPlayer === 'X' ? 'O' : 'X';
    playerDisplay.innerText = currentPlayer;
    playerDisplay.classList.add(`player${currentPlayer}`);
}


现在我们将编写宣布最终游戏结果的 announer 函数。它将接收结束游戏类型并innerText根据结果更新播音员 DOM 节点的 。在最后一行中,我们必须删除隐藏类,因为播音员默认是隐藏的,直到游戏结束。


const announce = (type) => {
    switch(type){
       case PLAYERO_WON:
            announcer.innerHTML = 'Player <span class="playerO">O</span> Won';
            break;
       case PLAYERX_WON:
            announcer.innerHTML = 'Player <span class="playerX">X</span> Won';
            break;
       case TIE:
            announcer.innerText = 'Tie';
        }
    announcer.classList.remove('hide');
};


接下来我们将编写这个项目中最有趣的部分之一——结果评估。首先,我们将创建一个 roundWon 变量并将其初始化为 false。然后我们将遍历winConditions数组并检查棋盘上的每个获胜条件。例如,在第二次迭代中,我们将检查这些值:board3、board4、board5。


我们还将进行一些优化,如果任何字段为空,我们将调用continue并跳到下一次迭代,因为如果获胜条件中有空图块,您将无法获胜。如果所有字段都相等,那么我们就有一个赢家,因此我们将 roundWon 设置为 true 并中断 for 循环,因为任何进一步的迭代都会浪费计算。


在循环之后,我们将检查roundWon变量的值,如果为真,我们将宣布获胜者并将游戏设置为非活动状态。如果我们没有获胜者,我们将检查棋盘上是否有空牌,如果我们没有获胜者并且没有空牌,我们将宣布平局。

function handleResultValidation() {
  let roundWon = false;
  for (let i = 0; i <= 7; i++) {
    const winCondition = winningConditions[i];
    const a = board[winCondition[0]];
    const b = board[winCondition[1]];
    const c = board[winCondition[2]];
    if (a === "" || b === "" || c === "") {
      continue;
    }
    if (a === b && b === c) {
      roundWon = true;
      break;
    }
  }
  if (roundWon) {
    announce(currentPlayer === "X" ? PLAYERX_WON : PLAYERO_WON);
    isGameActive = false;
    return;
  }
  if (!board.includes("")) announce(TIE);
}


接下来我们将处理用户的操作。此函数将接收一个 tile 和一个索引作为参数。当用户单击一个图块时,将调用此函数。首先我们需要检查它是否是一个有效的动作,我们还将检查游戏当前是否处于活动状态。如果两者都为真,我们innerText用当前玩家的符号更新瓷砖的 ,添加相应的类并更新板阵列。现在一切都更新了,我们必须检查游戏是否已经结束,所以我们调用handleResultValidation(). 最后,我们必须调用该changePlayer方法将轮次传递给另一个玩家。


const userAction = (tile, index) => {
  if (isValidAction(tile) && isGameActive) {
    tile.innerText = currentPlayer;
    tile.classList.add(`player${currentPlayer}`);
    updateBoard(index);
    handleResultValidation();
    changePlayer();
  }
};


为了让游戏正常运行,我们必须向磁贴添加事件侦听器。我们可以通过循环遍历图块数组并为每个图块添加一个事件侦听器来做到这一点。(为了获得更好的性能,我们只能向容器添加一个事件侦听器并使用事件冒泡来捕获父级上的磁贴点击,但我认为对于初学者来说这更容易理解。)


tiles.forEach( (tile, index) => {
    tile.addEventListener('click', () => userAction(tile, index));
});


我们只错过了一项功能:重置游戏。为此,我们将编写一个resetBoard函数。在此函数中,我们将棋盘设置X为由九个空字符串组成,将游戏设置为活动状态,移除播音员并将玩家更改回(根据定义X始终开始)。


我们必须做的最后一件事是遍历图块并将innerText 设置回空字符串,并从图块中删除任何特定于玩家的类。


const resetBoard = () => {
    board = ['', '', '', '', '', '', '', '', ''];
    isGameActive = true;
    announcer.classList.add('hide');
    if (currentPlayer === 'O') {
        changePlayer();
    }
    tiles.forEach(tile => {
        tile.innerText = '';
        tile.classList.remove('playerX');
        tile.classList.remove('playerO');
    });
}


现在我们只需要将此函数注册为重置按钮的点击事件处理程序。


resetButton.addEventListener('click', resetBoard);


就是这样,我们有一个功能齐全的井字游戏,你可以和你的朋友一起玩,玩得开心。


目录
相关文章
|
24天前
|
JavaScript 前端开发 Go
CSS 与 JS 对 DOM 解析和渲染的影响
【10月更文挑战第16天】CSS 和 JS 会在一定程度上影响 DOM 解析和渲染,了解它们之间的相互作用以及采取适当的优化措施是非常重要的。通过合理的布局和加载策略,可以提高网页的性能和用户体验,确保页面能够快速、流畅地呈现给用户。在实际开发中,要根据具体情况进行权衡和调整,以达到最佳的效果。
|
11天前
|
前端开发 JavaScript
如何在 JavaScript 中访问和修改 CSS 变量?
【10月更文挑战第28天】通过以上方法,可以在JavaScript中灵活地访问和修改CSS变量,从而实现根据用户交互、页面状态等动态地改变页面样式,为网页添加更多的交互性和动态效果。在实际应用中,可以根据具体的需求和场景选择合适的方法来操作CSS变量。
|
11天前
|
前端开发 JavaScript 数据处理
CSS 变量的作用域和 JavaScript 变量的作用域有什么不同?
【10月更文挑战第28天】CSS变量和JavaScript变量虽然都有各自的作用域概念,但由于它们所属的语言和应用场景不同,其作用域的定义、范围、覆盖规则以及与其他语言特性的交互方式等方面都存在明显的差异。理解这些差异有助于更好地在Web开发中分别运用它们来实现预期的页面效果和功能逻辑。
|
2天前
|
缓存 前端开发 JavaScript
优化CSS和JavaScript加载
Next.js和Nuxt.js在优化CSS和JavaScript加载方面提供了多种策略和工具。Next.js通过代码拆分、图片优化和特定的CSS/JavaScript优化措施提升性能;Nuxt.js则通过代码分割、懒加载、预渲染静态页面、Webpack配置和服务端缓存来实现优化。两者均能有效提高应用性能。
|
2天前
|
前端开发 JavaScript
用HTML CSS JS打造企业级官网 —— 源码直接可用
必看!用HTML+CSS+JS打造企业级官网-源码直接可用,文章代码仅用于学习,禁止用于商业
27 1
|
7天前
|
前端开发 JavaScript 安全
HTML+CSS+JS密码灯登录表单
通过结合使用HTML、CSS和JavaScript,我们创建了一个带有密码强度指示器的登录表单。这不仅提高了用户体验,还帮助用户创建更安全的密码。希望本文的详细介绍和代码示例能帮助您在实际项目中实现类似功能,提升网站的安全性和用户友好性。
17 3
|
10天前
|
JavaScript
JS鼠标框选并删除HTML源码
这是一个js鼠标框选效果,可实现鼠标右击出现框选效果的功能。右击鼠标可拖拽框选元素,向下拖拽可实现删除效果,简单实用,欢迎下载
22 4
|
11天前
|
前端开发 JavaScript UED
如何使用 JavaScript 动态修改 CSS 变量的值?
【10月更文挑战第28天】使用JavaScript动态修改CSS变量的值可以为页面带来更丰富的交互效果和动态样式变化,根据不同的应用场景和需求,可以选择合适的方法来实现CSS变量的动态修改,从而提高页面的灵活性和用户体验。
|
9天前
|
移动开发 HTML5
html5+three.js公路开车小游戏源码
html5公路开车小游戏是一款html5基于three.js制作的汽车开车小游戏源代码,在公路上开车网页小游戏源代码。
28 0
html5+three.js公路开车小游戏源码

热门文章

最新文章