一个好玩的井字棋的js源代码
今天我带大家来看看一个经典的小游戏实现——井字棋。通过分析它的源码,我们不仅能学到基本的前端布局技巧,还能更深入了解如何运用JavaScript进行逻辑控制和用户交互。好了,废话不多说,咱们开始刨析。
1. HTML 结构
先从HTML结构入手。整个页面非常简洁,主要由一个<table>
元素来构建棋盘,这个设计很合理。利用表格天然的行列布局特性,能方便地把井字棋的棋盘布局成3x3的格子。在源码中,HTML部分的结构是这样的:
<table class="xo">
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</table>
每个<td>
就是棋盘的一个格子。这里,我们使用了CSS来调整每个格子的大小和边框,这样用户点击时有清晰的视觉反馈。
2. CSS 样式
CSS部分用了大量的自定义属性和伪类,尤其是颜色主题切换和玩家轮换标志的处理。这里有一个比较有趣的点:通过--player-1-clr
和--player-2-clr
这两个CSS变量来动态设置不同玩家的颜色:
--player-1-clr: light-dark(oklch(0.5 0.15 200 / 1), oklch(0.7 0.07 200 / 1));
--player-2-clr: light-dark(oklch(0.75 0.2 20 / 1), oklch(0.7 0.15 20 / 1));
通过设置这些变量,不同的玩家下棋时,页面的整体颜色会根据玩家变换,这样不仅能提升用户体验,也让页面变得更加生动有趣。
3. JavaScript 实现
井字棋的核心逻辑主要通过JavaScript来实现。这里的核心思路是每次用户点击某个格子时,系统判断当前轮到哪位玩家,并在相应的格子上显示玩家的标记(比如“X”或“O”)。同时,JS还要处理胜负判断,以及提示是否要重新开始游戏。
点击事件处理
每当用户点击一个格子时,程序会调用一个点击事件处理函数,来判断当前是哪个玩家的回合,并在合适的地方标记玩家的标志。下面是一个典型的事件处理代码示例:
document.querySelectorAll('td').forEach(cell => {
cell.addEventListener('click', function () {
if (!cell.textContent) { // 判断该格子是否为空
cell.textContent = currentPlayer === 'X' ? 'X' : 'O';
switchPlayer();
}
});
});
这个简单的事件监听器确保玩家不能覆盖已有的棋子,并在每次点击后切换玩家。currentPlayer
是一个全局变量,存储当前是“X”还是“O”的回合。
胜负判断逻辑
这个部分的逻辑稍微复杂一些,我们需要遍历所有可能的胜利组合(横排、竖排、对角线),判断是否有玩家成功连成一线。具体实现时,可以把所有的胜利组合预先存储在一个数组中,循环检查这些组合:
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] // 对角线
];
function checkWinner() {
let winner = null;
winningCombinations.forEach(combination => {
const [a, b, c] = combination;
if (cells[a].textContent && cells[a].textContent === cells[b].textContent && cells[a].textContent === cells[c].textContent) {
winner = cells[a].textContent;
}
});
return winner;
}
这里的cells
数组存储了每个格子的状态(X、O或空)。通过循环遍历所有可能的组合,我们可以轻松地判断游戏是否结束。
4. 游戏重置
当游戏结束后,玩家可以点击“重新开始”按钮,程序会将所有格子重置为空,并重新设置currentPlayer
的值。下面是一个简单的重置函数:
function resetGame() {
cells.forEach(cell => cell.textContent = '');
currentPlayer = 'X'; // 重新设置为X先手
}
这个功能非常简单,但在实际开发中,要确保每次点击“重置”按钮后,游戏状态能够完全恢复初始状态。
从技术实现角度来看,井字棋虽然是一个相对简单的小游戏,但其中涉及的几个关键点还是值得注意的。
- 事件绑定与DOM操作:由于井字棋的每个格子都需要独立响应点击事件,因此需要给每个
<td>
绑定事件监听器,这涉及到基本的DOM操作。这里的重点是要确保每个事件都能准确响应并处理,避免重复绑定或者内存泄露等问题。 - 游戏状态管理:每个格子的状态(空、X或O)需要实时更新并存储,我们在实现中通过一个数组
cells
来保存状态。这种游戏状态的管理在多人交互中尤为重要,确保数据一致性至关重要。 - 视觉反馈与用户体验:通过CSS的动态变化,比如当前玩家的标志颜色、点击后的动画效果等,可以显著提升用户的游戏体验。源码中还用了伪类和CSS变量,增强了视觉的切换感和反馈,这种细节处理虽然不是难点,但非常重要。
结尾
通过井字棋这个小游戏,我们不仅可以熟悉HTML的基本布局,还能进一步了解如何通过JavaScript处理用户交互,以及如何利用CSS优化视觉效果和用户体验。最关键的是,这个小游戏逻辑简单但涉及的技术点不少,对于前端开发者来说是个很好的练手项目。