前面有写过一个 JavaScript 通过DOM操作的版本 JS五子棋
/**
*初始化棋盘
*
* @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)
源码下载