古老的五子棋

午休忽然想起我奶奶喜欢下的一种古老的五子棋游戏,于是花了半小时开发出来了~

源代码:

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>

效果图:

相关推荐
傻虎贼头贼脑10 分钟前
day21JS-npm中的部分插件使用方法
前端·npm·node.js
小胖伦的夕阳粉20 分钟前
js 获取树节点上某节点的最底层叶子节点数据
开发语言·javascript·ecmascript
low神21 分钟前
前端在网络安全攻击问题上能做什么?
前端·安全·web安全
@听风吟36 分钟前
力扣之182.查找重复的电子邮箱
大数据·javascript·数据库·sql·leetcode
qbbmnnnnnn1 小时前
【CSS Tricks】如何做一个粒子效果的logo
前端·css
唐家小妹1 小时前
【flex-grow】计算 flex弹性盒子的子元素的宽度大小
前端·javascript·css·html
涔溪1 小时前
uni-app环境搭建
前端·uni-app
安冬的码畜日常1 小时前
【CSS in Depth 2 精译_032】5.4 Grid 网格布局的显示网格与隐式网格(上)
前端·css·css3·html5·网格布局·grid布局·css网格布局
洛千陨1 小时前
element-plus弹窗内分页表格保留勾选项
前端·javascript·vue.js
小小19921 小时前
elementui 单元格添加样式的两种方法
前端·javascript·elementui