有没有想过,不用框架、不靠第三方库,只用最基础的 HTML + CSS + JS,写出一个可以点、可以走、还能悔棋的中国象棋小游戏?
今天,带你一步步从 0 开始,搭建一个能玩的网页版象棋! <br/>最后还有完整源码,直接拿来练手、改造!
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>简易象棋</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>简易象棋</h1>
<div id="controls">
<button onclick="restartGame()">重新开始</button>
<button onclick="undoMove()">悔棋</button>
</div>
<div id="chessboard"></div>
<script src="script.js"></script>
</body>
</html>
结构非常简单,主体分为:标题、控制按钮区、棋盘区域。
body {
font-family: Arial, sans-serif;
text-align: center;
background: #f5f5dc;
}
h1 {
margin-top: 20px;
}
#controls {
margin-bottom: 10px;
}
#chessboard {
width: 450px;
height: 500px;
margin: 0 auto;
display: grid;
grid-template-columns: repeat(9, 1fr);
grid-template-rows: repeat(10, 1fr);
border: 2px solid #333;
background: #ffe4c4;
position: relative;
}
.cell {
border: 1px solid #333;
position: relative;
}
.piece {
width: 90%;
height: 90%;
margin: 5%;
border-radius: 50%;
background: #d9b382;
display: flex;
justify-content: center;
align-items: center;
font-size: 18px;
cursor: pointer;
user-select: none;
}
.red {
color: red;
}
.black {
color: black;
}
让棋盘有格子,有背景,棋子圆圆胖胖,看着更舒服。
const board = document.getElementById('chessboard');
let selectedPiece = null;
let selectedCell = null;
let moveHistory = [];
const initialPieces = {
"0,0": { text: "车", color: "black" },
"1,0": { text: "马", color: "black" },
"2,0": { text: "象", color: "black" },
"3,0": { text: "士", color: "black" },
"4,0": { text: "将", color: "black" },
"5,0": { text: "士", color: "black" },
"6,0": { text: "象", color: "black" },
"7,0": { text: "马", color: "black" },
"8,0": { text: "车", color: "black" },
"1,2": { text: "炮", color: "black" },
"7,2": { text: "炮", color: "black" },
"0,3": { text: "兵", color: "black" },
"2,3": { text: "兵", color: "black" },
"4,3": { text: "兵", color: "black" },
"6,3": { text: "兵", color: "black" },
"8,3": { text: "兵", color: "black" },
"0,9": { text: "车", color: "red" },
"1,9": { text: "马", color: "red" },
"2,9": { text: "相", color: "red" },
"3,9": { text: "仕", color: "red" },
"4,9": { text: "帅", color: "red" },
"5,9": { text: "仕", color: "red" },
"6,9": { text: "相", color: "red" },
"7,9": { text: "马", color: "red" },
"8,9": { text: "车", color: "red" },
"1,7": { text: "炮", color: "red" },
"7,7": { text: "炮", color: "red" },
"0,6": { text: "兵", color: "red" },
"2,6": { text: "兵", color: "red" },
"4,6": { text: "兵", color: "red" },
"6,6": { text: "兵", color: "red" },
"8,6": { text: "兵", color: "red" },
};
function createBoard() {
board.innerHTML = '';
for (let y = 0; y < 10; y++) {
for (let x = 0; x < 9; x++) {
const cell = document.createElement('div');
cell.className = 'cell';
cell.dataset.x = x;
cell.dataset.y = y;
const key = `${x},${y}`;
if (initialPieces[key]) {
const piece = document.createElement('div');
piece.className = `piece ${initialPieces[key].color}`;
piece.innerText = initialPieces[key].text;
cell.appendChild(piece);
}
cell.addEventListener('click', onCellClick);
board.appendChild(cell);
}
}
}
function onCellClick(e) {
const cell = e.currentTarget;
const piece = cell.querySelector('.piece');
if (selectedPiece) {
if (!piece || selectedPiece.classList.contains('red') !== piece.classList.contains('red')) {
moveHistory.push({
fromX: selectedCell.dataset.x,
fromY: selectedCell.dataset.y,
toX: cell.dataset.x,
toY: cell.dataset.y,
movedPiece: selectedPiece,
capturedPiece: piece
});
if (piece) {
piece.remove();
}
cell.appendChild(selectedPiece);
selectedPiece.style.border = "none";
if (piece && (piece.innerText === "帅" || piece.innerText === "将")) {
alert((piece.classList.contains('red') ? "黑方胜利!" : "红方胜利!"));
restartGame();
return;
}
} else {
alert("不能吃自己人!");
}
selectedPiece = null;
selectedCell = null;
} else if (piece) {
selectedPiece = piece;
selectedCell = cell;
piece.style.border = "2px solid blue";
}
}
function restartGame() {
selectedPiece = null;
selectedCell = null;
moveHistory = [];
createBoard();
}
function undoMove() {
if (moveHistory.length === 0) {
alert("没有可以悔棋的步骤!");
return;
}
const lastMove = moveHistory.pop();
const fromCell = getCell(lastMove.fromX, lastMove.fromY);
const toCell = getCell(lastMove.toX, lastMove.toY);
fromCell.appendChild(lastMove.movedPiece);
if (lastMove.capturedPiece) {
toCell.appendChild(lastMove.capturedPiece);
}
}
function getCell(x, y) {
return document.querySelector(`.cell[data-x="${x}"][data-y="${y}"]`);
}
createBoard();
虽然这个象棋项目比较基础:
但作为前端练习小项目,完美够用!
想要继续升级?可以考虑:

