四川省建設(shè)資格注冊中心網(wǎng)站重慶seo公司怎么樣
The sand accumulates to form a pagoda
- ? 寫在前面
- ? 功能介紹
- ? 頁面搭建
- ? 樣式設(shè)置
- ? 邏輯部分
? 寫在前面
上周我們實通過前端基礎(chǔ)實現(xiàn)了飛機大戰(zhàn)游戲,今天還是繼續(xù)按照我們原定的節(jié)奏來帶領(lǐng)大家完成一個井字游戲游戲,功能也比較簡單簡單,也是想借助這樣一個簡單的功能,然后來幫助大家了解我們JavaScript在前端中的作用, 在前面的文章當(dāng)中我們也提及到我們在本系列的專欄是循序漸進從簡單到復(fù)雜的過程,后續(xù)會帶領(lǐng)大家用前端實現(xiàn)翻卡片、掃雷、貪吃蛇等有趣的小游戲,純前端語言實現(xiàn),都會陸續(xù)帶給大家。歡迎大家訂閱我們這份前端小游戲的專欄。訂閱鏈接:https://blog.csdn.net/jhxl_/category_12261013.html
? 功能介紹
井字游戲是一款經(jīng)典的策略性棋盤游戲,也被稱為井字棋或三子棋。游戲通過在3x3的棋盤上輪流落子,目標是將自己的棋子以橫、豎或?qū)蔷€的形式連成一條線,先達成連線的一方獲勝。這款游戲簡單易學(xué),但需要一定的思考和策略,是一款適合所有年齡段的休閑游戲。
游戲開始時,棋盤上顯示一個3x3的網(wǎng)格,玩家扮演的是"X"棋子,計算機扮演的是"O"棋子。玩家和計算機輪流落子,每個回合可以在空白的格子中放置自己的棋子。玩家通過點擊空白格子來放置"X"棋子,計算機會自動進行下棋。當(dāng)任意一方的棋子以橫、豎或?qū)蔷€的形式連成一條線時,該方獲得勝利。如果棋盤填滿且沒有任何一方獲勝,則游戲為平局。挑戰(zhàn)計算機,思考最佳策略,爭取在井字游戲中獲得勝利吧!
? 頁面搭建
創(chuàng)建文件
首先呢我們創(chuàng)建我們的HTML文件,這里我就直接命名為 井字游戲.html
了,大家可以隨意命名, 文件創(chuàng)建生成后我們通過編輯器打開,這里我用的是VScode, 然后初始化我們的代碼結(jié)構(gòu),那在這里告訴大家一個快捷鍵,就是我們敲上我們英文的一個 !
我們敲擊回車直接就會給我們生成基礎(chǔ)版本的前端代碼結(jié)構(gòu)。
文檔聲明和編碼設(shè)置: 在HTML文檔的頭部,使用<!DOCTYPE>聲明HTML文檔類型,確保瀏覽器以正確的方式渲染網(wǎng)頁內(nèi)容。同時,設(shè)置UTF-8編碼,以確保瀏覽器能夠正確地解析和顯示中文字符。下面我就開始搭建我們的DOM結(jié)構(gòu)了!
DOM結(jié)構(gòu)搭建
這段HTML代碼表示一個井字游戲的棋盤。讓我為來看下每部分的含義吧!<div class="board">
:這是游戲的棋盤容器,表示整個游戲區(qū)域。 <div class="cell">
:這是每個格子,用于放置玩家和計算機的棋子。這里共有9個格子,按照3x3的形式排列,代表了井字游戲的九個位置。<div id="result"></div>
:這是用于顯示游戲結(jié)果的區(qū)域,初始時是空的。
在這個HTML結(jié)構(gòu)中,通過使用CSS樣式和JavaScript代碼,可以實現(xiàn)井字游戲的顯示、交互和結(jié)果展示。玩家可以點擊格子,在空白的位置放置自己的棋子,然后計算機會根據(jù)規(guī)則進行下一步的落子,最終判斷是否有玩家獲勝或者平局。當(dāng)然我們寫上下面代碼打開頁面也是空白的,因為我們雖然寫了標簽,但是標簽里面沒有任何內(nèi)容!
<div class="board"><div class="cell"></div><div class="cell"></div><div class="cell"></div><div class="cell"></div><div class="cell"></div><div class="cell"></div><div class="cell"></div><div class="cell"></div><div class="cell"></div>
</div>
<div id="result"></div>
? 樣式設(shè)置
我們看到了上面的的DOM已經(jīng)搭建好了,但是頁面什么都看不出來,下面我們簡單的來配置一下樣式吧,其實我們本專欄也是想帶領(lǐng)大家掌握一些邏輯所以樣式方面我們就一切從簡;
這段樣式代碼定義了游戲界面的外觀和布局。讓我為小白逐個解釋每個樣式的含義:
.board
:這是一個類選擇器,用于選擇游戲棋盤的容器元素。
display: grid;
:設(shè)置元素的布局方式為網(wǎng)格布局。grid-template-columns: repeat(3, 1fr);
:定義了網(wǎng)格的列數(shù)為 3,每列的寬度平均分配。grid-template-rows: repeat(3, 1fr);
:定義了網(wǎng)格的行數(shù)為 3,每行的高度平均分配。gap: 5px;
:設(shè)置了網(wǎng)格之間的間隔為 5px。width: 300px;
:設(shè)置了容器的寬度為 300px。height: 300px;
:設(shè)置了容器的高度為 300px。margin: 0 auto;
:使容器在水平方向上居中對齊。border: 1px solid #ccc;
:設(shè)置容器的邊框為 1px 的實線邊框,顏色為 #ccc。padding: 5px;
:設(shè)置容器的內(nèi)邊距為 5px。
.cell
:這是一個類選擇器,用于選擇游戲棋盤中的每個單元格元素。
display: flex;
:設(shè)置元素的布局方式為彈性布局。align-items: center;
:在交叉軸上居中對齊元素內(nèi)容。justify-content: center;
:在主軸上居中對齊元素內(nèi)容。font-size: 24px;
:設(shè)置字體大小為 24px。font-weight: bold;
:設(shè)置字體加粗。background-color: #f2f2f2;
:設(shè)置背景顏色為 #f2f2f2,即淺灰色。cursor: pointer;
:將鼠標光標設(shè)置為手型指示器,表示單元格可以點擊。
#result
:這是一個 ID 選擇器,用于選擇游戲結(jié)果信息的元素。
text-align: center;
:將文本內(nèi)容居中對齊。font-size: 24px;
:設(shè)置字體大小為 24px。margin-top: 20px;
:設(shè)置頂部外邊距為 20px,用于與上方元素保持一定的間距。
這些樣式定義了游戲界面的布局、單元格的樣式和游戲結(jié)果信息的樣式,使界面看起來更加整齊、美觀,并提供了互動性和可點擊性。
<style>.board {display: grid;grid-template-columns: repeat(3, 1fr);grid-template-rows: repeat(3, 1fr);gap: 5px;width: 300px;height: 300px;margin: 0 auto;border: 1px solid #ccc;padding: 5px;}.cell {display: flex;align-items: center;justify-content: center;font-size: 24px;font-weight: bold;background-color: #f2f2f2;cursor: pointer;}#result {text-align: center;font-size: 24px;margin-top: 20px;}
</style>
? 邏輯部分
上面我們搭建了基本的樣式,下面呢我們就通過js代碼,實現(xiàn)我們游戲的功能吧首先我們定義了一些變量,來使用:
const board
:表示游戲棋盤的狀態(tài)數(shù)組,存儲每個格子的標記。const cells
:存儲所有格子的元素,用于操作和監(jiān)聽每個格子。const resultElement
:用于顯示游戲結(jié)果的元素。let currentPlayer
:表示當(dāng)前玩家的標記,初始為 “X”。let gameEnded
:表示游戲是否結(jié)束的標志,初始為false
。
const board = ["", "", "", "", "", "", "", "", ""];
const cells = document.querySelectorAll(".cell");
const resultElement = document.getElementById("result");
let currentPlayer = "X";
let gameEnded = false;
同時我們編寫了一些函數(shù),下面就是每個函數(shù)的大致作用:
updateGameState(cellIndex)
:更新游戲狀態(tài),處理玩家的移動。checkWin(player)
:檢查玩家是否獲勝。checkDraw()
:檢查游戲是否平局。endGame(message)
:結(jié)束游戲,顯示最終結(jié)果。makeComputerMove()
:模擬電腦進行移動。renderBoard()
:渲染棋盤狀態(tài)。resetGame()
:重置游戲為初始狀態(tài)。
最后,通過監(jiān)聽格子的點擊事件,調(diào)用 updateGameState
函數(shù)處理玩家的移動,并在頁面加載完成后調(diào)用 resetGame
函數(shù)初始化游戲。
<script>function updateGameState(cellIndex) {if (!gameEnded && board[cellIndex] === "") {board[cellIndex] = currentPlayer;renderBoard();if (checkWin(currentPlayer)) {endGame("Player " + currentPlayer + " wins!");} else if (checkDraw()) {endGame("It's a draw!");} else {currentPlayer = currentPlayer === "X" ? "O" : "X";if (currentPlayer === "O") {setTimeout(makeComputerMove, 500);}}}}function checkWin(player) {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] === player && board[b] === player && board[c] === player) {return true;}}return false;}function checkDraw() {return board.every(cell => cell !== "");}function endGame(message) {gameEnded = true;resultElement.textContent = message;}function makeComputerMove() {const emptyCells = board.reduce((acc, cell, index) => {if (cell === "") {acc.push(index);}return acc}, []);if (emptyCells.length > 0) {const randomIndex = Math.floor(Math.random() * emptyCells.length);const computerMove = emptyCells[randomIndex];updateGameState(computerMove);}}function renderBoard() {for (let i = 0; i < cells.length; i++) {cells[i].textContent = board[i];}}function resetGame() {board.fill("");currentPlayer = "X";gameEnded = false;resultElement.textContent = "";renderBoard();}cells.forEach((cell, index) => {cell.addEventListener("click", () => updateGameState(index));});resetGame();
</script>
完整代碼
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>.board {display: grid;grid-template-columns: repeat(3, 1fr);grid-template-rows: repeat(3, 1fr);gap: 5px;width: 300px;height: 300px;margin: 0 auto;border: 1px solid #ccc;padding: 5px;}.cell {display: flex;align-items: center;justify-content: center;font-size: 24px;font-weight: bold;background-color: #f2f2f2;cursor: pointer;}#result {text-align: center;font-size: 24px;margin-top: 20px;}</style>
</head><body><div class="board"><div class="cell"></div><div class="cell"></div><div class="cell"></div><div class="cell"></div><div class="cell"></div><div class="cell"></div><div class="cell"></div><div class="cell"></div><div class="cell"></div></div><div id="result"></div>
</body><script>const board = ["", "", "", "", "", "", "", "", ""];const cells = document.querySelectorAll(".cell");const resultElement = document.getElementById("result");let currentPlayer = "X";let gameEnded = false;function updateGameState(cellIndex) {if (!gameEnded && board[cellIndex] === "") {board[cellIndex] = currentPlayer;renderBoard();if (checkWin(currentPlayer)) {endGame("Player " + currentPlayer + " wins!");} else if (checkDraw()) {endGame("It's a draw!");} else {currentPlayer = currentPlayer === "X" ? "O" : "X";if (currentPlayer === "O") {setTimeout(makeComputerMove, 500);}}}}function checkWin(player) {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] === player && board[b] === player && board[c] === player) {return true;}}return false;}function checkDraw() {return board.every(cell => cell !== "");}function endGame(message) {gameEnded = true;resultElement.textContent = message;}function makeComputerMove() {const emptyCells = board.reduce((acc, cell, index) => {if (cell === "") {acc.push(index);}return acc}, []);if (emptyCells.length > 0) {const randomIndex = Math.floor(Math.random() * emptyCells.length);const computerMove = emptyCells[randomIndex];updateGameState(computerMove);}}function renderBoard() {for (let i = 0; i < cells.length; i++) {cells[i].textContent = board[i];}}function resetGame() {board.fill("");currentPlayer = "X";gameEnded = false;resultElement.textContent = "";renderBoard();}cells.forEach((cell, index) => {cell.addEventListener("click", () => updateGameState(index));});resetGame();
</script></html>
本期推薦 點擊此處購買
? 原創(chuàng)不易,還希望各位大佬支持一下 \textcolor{blue}{原創(chuàng)不易,還希望各位大佬支持一下} 原創(chuàng)不易,還希望各位大佬支持一下
👍 點贊,你的認可是我創(chuàng)作的動力! \textcolor{green}{點贊,你的認可是我創(chuàng)作的動力!} 點贊,你的認可是我創(chuàng)作的動力!
?? 收藏,你的青睞是我努力的方向! \textcolor{green}{收藏,你的青睞是我努力的方向!} 收藏,你的青睞是我努力的方向!
?? 評論,你的意見是我進步的財富! \textcolor{green}{評論,你的意見是我進步的財富!} 評論,你的意見是我進步的財富!