午休忽然想起我奶奶喜欢下的一种古老的五子棋游戏,于是花了半小时开发出来了~
源代码:
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>棋盘图案</title>
<style>
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #faf1c0;
}
canvas {
background-color: #DAA520; /* 黄棕色 */
border: 1px solid black;
}
</style>
</head>
<body>
<canvas id="chessboard" width="600" height="600"></canvas>
<script>
const canvas = document.getElementById('chessboard');
const ctx = canvas.getContext('2d');
// 棋子信息存储
let pieces = [];
// 棋盘信息存储
let board = { size: canvas.width, margin: canvas.width * 0.05, step: (canvas.width - canvas.width * 0.1) / 4 };
board.drawableSize = board.size - 2 * board.margin;
// 当前拖拽的棋子
let currentPiece = null;
function drawPiece(x, y, color, isDragging = false) {
const radius = board.size / 28; // 棋子的半径,可以根据需要调整
ctx.beginPath();
ctx.arc(x, y, radius, 0, Math.PI * 2);
ctx.fillStyle = color;
ctx.fill();
if (isDragging) {
ctx.strokeStyle = 'red';
ctx.stroke();
}
ctx.closePath();
return { x, y, radius, color };
}
function drawChessboard() {
ctx.clearRect(0, 0, board.size, board.size);
for (let i = 0; i <= 4; i++) {
ctx.moveTo(board.margin, board.margin + i * board.step);
ctx.lineTo(board.margin + board.drawableSize, board.margin + i * board.step);
ctx.moveTo(board.margin + i * board.step, board.margin);
ctx.lineTo(board.margin + i * board.step, board.margin + board.drawableSize);
}
let size = board.size
let step = board.step
let margin = board.margin
// 画对角线
ctx.moveTo(margin, margin);
ctx.lineTo(size-margin, size-margin);
ctx.moveTo(margin, size-margin);
ctx.lineTo(size-margin, margin);
ctx.moveTo(margin, 2*step+margin);
ctx.lineTo(2 * step+margin, size-margin);
ctx.moveTo(2*step+margin, margin);
ctx.lineTo(size-margin, 2 * step+margin);
ctx.moveTo(margin, 2 * step+margin);
ctx.lineTo(2 * step+margin, margin);
ctx.moveTo(2*step+margin, size-margin);
ctx.lineTo(size-margin, 2*step+margin);
ctx.stroke();
ctx.stroke();
}
// 初始化棋子
function initPieces() {
pieces = [];
// 画白色棋子
for (let i = 0; i <= 4; i++) {
pieces.push(drawPiece(i * board.step + board.margin, board.margin, 'white'));
}
// 画黑色棋子
for (let i = 0; i <= 4; i++) {
pieces.push(drawPiece(i * board.step + board.margin, board.size - board.margin, 'black'));
}
}
// 检测坐标是否在棋子上
function isPieceUnderCoordinate(x, y, piece) {
const distance = Math.sqrt((x - piece.x) ** 2 + (y - piece.y) ** 2);
return distance < piece.radius;
}
// 开始拖拽
canvas.onmousedown = function(event) {
const rect = canvas.getBoundingClientRect();
const x = event.clientX - rect.left;
const y = event.clientY - rect.top;
for (const piece of pieces) {
if (isPieceUnderCoordinate(x, y, piece)) {
currentPiece = piece;
break;
}
}
};
// 拖拽移动
canvas.onmousemove = function(event) {
if (currentPiece) {
const rect = canvas.getBoundingClientRect();
const x = event.clientX - rect.left;
const y = event.clientY - rect.top;
drawChessboard();
for (const piece of pieces) {
if (piece === currentPiece) {
drawPiece(x, y, piece.color, true);
} else {
drawPiece(piece.x, piece.y, piece.color);
}
}
}
};
// 放下棋子
canvas.onmouseup = function(event) {
if (currentPiece) {
const rect = canvas.getBoundingClientRect();
const x = event.clientX - rect.left;
const y = event.clientY - rect.top;
// 计算最接近的交点
const closestX = Math.round((x - board.margin) / board.step) * board.step + board.margin;
const closestY = Math.round((y - board.margin) / board.step) * board.step + board.margin;
// 更新棋子位置
currentPiece.x = closestX;
currentPiece.y = closestY;
drawChessboard();
for (const piece of pieces) {
drawPiece(piece.x, piece.y, piece.color);
}
}
currentPiece = null;
};
// 双击切换棋子颜色
canvas.ondblclick = function(event) {
const rect = canvas.getBoundingClientRect();
const x = event.clientX - rect.left;
const y = event.clientY - rect.top;
for (const piece of pieces) {
if (isPieceUnderCoordinate(x, y, piece)) {
// 切换颜色
piece.color = piece.color === 'white' ? 'black' : 'white';
// 重新绘制棋盘和棋子
drawChessboard();
for (const piece of pieces) {
drawPiece(piece.x, piece.y, piece.color);
}
break;
}
}
};
drawChessboard();
initPieces();
</script>
</body>
</html>
效果图: