JavaScript简单五子棋(canvas)

JS 简单五子棋 canvas 版本

前面有写过一个 JavaScript 通过DOM操作的版本 JS五子棋

html代码

<body>
    <div class="bg" id="bg">
        <canvas id="myCanvas"></canvas>
    </div>
</body>

画棋盘

/**
 *初始化棋盘
 *
 * @param {*} canvas 画布
 * @param {*} canvasText 画笔
 * @param {*} n 
 */
function initChessboard(canvas, canvasText, n, s) {

    canvas.setAttribute('width', n * s + 60 + 'px');
    canvas.setAttribute('height', n * s + 60 + 'px')

    canvasText.strokeStyle = '#000';   // 画笔颜色
    for (let i = 0; i < n; i++) {

        canvasText.moveTo(30, i * s + 30);
        canvasText.lineTo(n * 30, i * s + 30);
        canvasText.stroke();

        canvasText.moveTo(i * s + 30, 30);
        canvasText.lineTo(i * s + 30, n * 30);
        canvasText.stroke();

        pieceArr[i] = [];

        for (let j = 0; j < n; j++) {
            pieceArr[i][j] = '0';
        }
    }

    // 背景大小
    document.querySelector('#bg').style.width = (n * s + 80) + 'px';
    document.querySelector('#bg').style.height = (n * s + 80) + 'px';
}

在这里插入图片描述

下棋

获取鼠标点击的坐标,在离点击点最近的棋盘交叉点上画上棋子

/**
 *画棋子
 *
 * @param {*} canvasText 画笔
 * @param {*} i x轴序号
 * @param {*} j y轴序号
 * @param {*} color  棋子颜色
 */
function drawPiece(canvasText, i, j, color) {
    let x = i * 30 + 30, y = j * 30 + 30;
    canvasText.beginPath();
    canvasText.arc(x, y, 13, 0, 2 * Math.PI);
    /**
     * createLinearGradient() 方法创建放射状/圆形渐变对象。
     * context.createRadialGradient(x0,y0,r0,x1,y1,r1);
     * x0   开始x坐标
     * y0   开始y坐标
     * r0   开始半径
     * x1   结束x坐标
     * y1   结束y坐标
     * r1   结束半径
     */
    var gradient = canvasText.createRadialGradient(x, y, size-2, x + 15, y + 15, 0)
    /**
     * addColorStop方法规定 gradient 对象中的颜色和位置
     * gradient.addColorStop(stop,color);
     * stop	介于 0.0 与 1.0 之间的值,表示渐变中开始与结束之间的位置。
     * color	在结束位置显示的 CSS 颜色值
     */
    if (color == 'black') {
        gradient.addColorStop(0, '#0a0a0a');
        gradient.addColorStop(1, '#636766');
    } else if (color == 'white') {
        gradient.addColorStop(0, '#d1d1d1');
        gradient.addColorStop(1, '#f9f9f9');
    }

    canvasText.fillStyle = gradient;
    canvasText.fill();

}


/**
 * 落子
 * @param {*} canvas 画布
 */
function play(canvas) {
    canvas.addEventListener('click', (e) => {
        if (!isOver) {
            let i = Math.round(e.offsetX / 30) - 1;
            let j = Math.round(e.offsetY / 30) - 1;
            if (pieceArr[j][i] == '0') {
                drawPiece(myCanvasText, i, j, pieceColor)
                pieceArr[j][i] = pieceColor;
                judgeWin(j, i, num, pieceColor);
                pieceColor = pieceColor == 'black' ? 'white' : 'black';
                textHint(myCanvasText, pieceColor, num, size)
            }
        }
    })
}

在这里插入图片描述

判胜

从4个方向(垂直、水平、45°、135°)分别判断是否有同一颜色的五子相连。

/**
 * 判胜
 *
 * @param {*} i x轴序号
 * @param {*} j y轴序号
 * @param {*} n
 * @param {*} color 棋子颜色
 */
function judgeWin(i, j, n, color) {

    let x, y, s;

    // 垂直方向
    s = 1;
    for (y = j + 1; y < n && y < j + 5; y++) {
        if (pieceArr[i][y] == color) {
            s++;
            gameOver(s, color);
        } else {
            break;
        }
    }
    for (y = j - 1; y >= 0 && y > j - 5; y--) {
        if (pieceArr[i][y] == color) {
            s++;
            gameOver(s, color);
        } else {
            break;
        }
    }
    // 水平方向
    s = 1;
    for (x = i + 1; x < n && x < i + 5; x++) {
        if (pieceArr[x][j] == color) {
            s++;
            gameOver(s, color);
        } else {
            break;
        }
    }
    for (x = i - 1; x >= 0 && x > i - 5; x--) {
        if (pieceArr[x][j] == color) {
            s++;
            gameOver(s, color);
        } else {
            break;
        }
    }

    // 45°方向
    s = 1;
    for (x = i + 1, y = j + 1; x < n && x < i + 5 && y < n && y < j + 5; x++ , y++) {

        if (pieceArr[x][y] == color) {
            s++;
            gameOver(s, color)
        } else {
            break;
        }
    }

    for (x = i - 1, y = j - 1; x >= 0 && x > i - 5 && y >= 0 && y > j - 5; x-- , y--) {

        if (pieceArr[x][y] == color) {
            s++;
            gameOver(s, color)
        } else {
            break;
        }
    }
    // 135°方向
    s = 1;
    for (x = i - 1, y = j + 1; x >= 0 && x > i - 5 && y < n && y < j + 5; x-- , y++) {

        if (pieceArr[x][y] == color) {
            s++;
            gameOver(s, color)
        } else {
            break;
        }
    }

    for (x = i + 1, y = j - 1; x < n && x < i + 5 && y >= 0 && y > j - 5; x++ , y--) {

        if (pieceArr[x][y] == color) {
            s++;
            gameOver(s, color)
        } else {
            break;
        }
    }

}

/**
 * 游戏结束函数
 *
 * @param {*} s 棋子个数
 * @param {*} color 棋子颜色
 */
function gameOver(s, color) {

    if (s == 5) {

        isOver = true;
        if (color == 'black') {
            // 添加黑子胜利样式
            document.querySelector('#bg').classList.add('black-win')

        } else {
            document.querySelector('#bg').classList.add('white-win')
        }
    }
}

在这里插入图片描述

函数调用

let num = 20; //棋盘交叉点总数 num*num
let size = 30; //格子大小 size*size
let isOver = false;
let myCanvas = document.querySelector('#myCanvas'); // 画布
let myCanvasText = myCanvas.getContext('2d') // 画笔
let pieceColor = 'black';   //默认黑色先

let pieceArr = [];  //地图数组 0-没棋子 white-白棋 black-黑棋 

initChessboard(myCanvas, myCanvasText, num, size)

textHint(myCanvasText, pieceColor, num, size)
play(myCanvas)

源码下载

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值