古老的五子棋

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

源代码:

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>

效果图:

相关推荐
子兮曰4 小时前
Bun v1.3.14 深度解析:Image API、HTTP/3、全局虚拟存储与五十项变革
前端·后端·bun
kyriewen5 小时前
今天,百年巨头一次砍了9200人,而一个离职科学家的实话让全网睡不着觉
前端·openai·ai编程
问心无愧05135 小时前
ctf show web 入门42
android·前端·android studio
kyriewen6 小时前
老板逼我上AI,我偷偷在浏览器里跑LLaMA,省下20万API费
前端·react.js·llm
Beginner x_u6 小时前
前端八股整理(手写 02)|数组转树、数组扁平化、随机打乱一个数组
前端·数组·数组转树·数组扁平化
KaMeidebaby6 小时前
卡梅德生物技术快报|禽类成纤维细胞 FISH 实验:鸟类性别染色体基因定位技术实现与数据验证
前端·数据库·其他·百度·新浪微博
天若有情6736 小时前
前端高阶性能优化:跳出传统懒加载与预加载,基于用户行为做轻量预判加载
前端·性能优化
小小小小宇6 小时前
前端转后端:SQL 是什么
前端
张元清7 小时前
React Observer Hooks:7 种监听 DOM 而不写样板代码的方式
前端·javascript·面试
广州华水科技7 小时前
单北斗GNSS变形监测是什么?主要有怎样的应用与优势?
前端