欢迎访问宙启技术站
智能推送

canvas实现五子棋游戏的代码示例

发布时间:2023-05-17 13:36:20

由于篇幅限制,这里我就提供一些核心代码片段,而不是完整的示例代码。

首先,在HTML中创建一个canvas元素和一些控制按钮:

<canvas id="chess" width="450" height="450"></canvas>
<button id="restart">重新开始</button>
<button id="undo">悔棋</button>
<div id="message"></div>

接下来,我们需要在JavaScript中获取canvas元素及其上下文,并初始化游戏状态。可以通过创建二维数组来表示棋盘,用0表示空白,用1和-1分别表示黑棋和白棋。

let canvas = document.querySelector("#chess");
let ctx = canvas.getContext("2d");
let board = new Array(15).fill(new Array(15).fill(0));
let isBlackTurn = true; // 黑子先手
let gameOver = false;
let message = document.querySelector("#message");

function init() {
  // 绘制背景
  ctx.fillStyle = "#EFEFEF";
  ctx.fillRect(0, 0, 450, 450);
  // 绘制棋盘格线
  ctx.strokeStyle = "#BFBFBF";
  for (let i = 0; i < 15; i++) {
    ctx.moveTo(15 + i * 30, 15);
    ctx.lineTo(15 + i * 30, 435);
    ctx.moveTo(15, 15 + i * 30);
    ctx.lineTo(435, 15 + i * 30);
    ctx.stroke();
  }
  // 初始化棋盘状态
  for (let i = 0; i < 15; i++) {
    board[i] = new Array(15).fill(0);
  }
  isBlackTurn = true;
  gameOver = false;
  message.innerHTML = "黑子先手";
}

接下来,我们需要处理用户的鼠标点击事件,并根据当前玩家下棋的位置更新棋盘状态。如果当前一方赢了游戏,或者棋盘已经下满,就需要停止游戏。

canvas.addEventListener("mousedown", function(e) {
  if (gameOver) { // 游戏已结束
    return;
  }
  let x = e.offsetX;
  let y = e.offsetY;
  let rowIndex = Math.floor(y / 30);
  let colIndex = Math.floor(x / 30);
  if (board[rowIndex][colIndex] !== 0) { // 该位置已经有棋子
    return;
  }
  // 绘制棋子
  ctx.beginPath();
  ctx.arc(15 + colIndex * 30, 15 + rowIndex * 30, 13, 0, Math.PI * 2);
  ctx.closePath();
  let gradient = ctx.createRadialGradient(
    15 + colIndex * 30 + 2, 15 + rowIndex * 30 - 2, 13,
    15 + colIndex * 30 + 2, 15 + rowIndex * 30 - 2, 0
  );
  if (isBlackTurn) {
    gradient.addColorStop(0, "#0A0A0A");
    gradient.addColorStop(1, "#636766");
    board[rowIndex][colIndex] = 1;
    message.innerHTML = "白子回合";
  } else {
    gradient.addColorStop(0, "#D1D1D1");
    gradient.addColorStop(1, "#F9F9F9");
    board[rowIndex][colIndex] = -1;
    message.innerHTML = "黑子回合";
  }
  ctx.fillStyle = gradient;
  ctx.fill();
  // 判断游戏是否结束
  if (checkWin(rowIndex, colIndex)) {
    gameOver = true;
    message.innerHTML = isBlackTurn ? "黑子胜利" : "白子胜利";
    return;
  }
  if (checkDraw()) {
    gameOver = true;
    message.innerHTML = "平局";
    return;
  }
  // 切换玩家
  isBlackTurn = !isBlackTurn;
});

// 判断游戏是否胜利
function checkWin(row, col) {
  let count1 = 1, count2 = 1, count3 = 1, count4 = 1;
  let cur = board[row][col];
  for (let i = 1; i <= 4; i++) {
    if (row + i >= 15 || board[row + i][col] !== cur) {
      break;
    }
    count1++;
  }
  for (let i = 1; i <= 4; i++) {
    if (col + i >= 15 || board[row][col + i] !== cur) {
      break;
    }
    count2++;
  }
  for (let i = 1; i <= 4; i++) {
    if (row + i >= 15 || col + i >= 15 || board[row + i][col + i] !== cur) {
      break;
    }
    count3++;
  }
  for (let i = 1; i <= 4; i++) {
    if (row - i < 0 || col + i >= 15 || board[row - i][col + i] !== cur) {
      break;
    }
    count4++;
  }
  return count1 >= 5 || count2 >= 5 || count3 >= 5 || count4 >= 5;
}

// 判断游戏是否平局
function checkDraw() {
  for (let row = 0; row < 15; row++) {
    for (let col = 0; col < 15; col++) {
      if (board[row][col] === 0) {
        return false;
      }
    }
  }
  return true;
}

最后,我们需要处理重新开始和悔棋按钮的逻辑:

let restartButton = document.querySelector("#restart");
restartButton.addEventListener("click", function() {
  init();
});

let undoButton = document.querySelector("#undo");
undoButton.addEventListener("click", function() {
  if (gameOver) { // 游戏已结束
    return;
  }
  let lastPiece = document.querySelector("#chess:last-child");
  if (!lastPiece) { // 棋盘上没有棋子
    return;
  }
  let x = parseInt(lastPiece.getAttribute("cx"));
  let y = parseInt(lastPiece.getAttribute("cy"));
  board[Math.floor(y / 30)][Math.floor(x / 30)] = 0; // 撤销最后一个棋子
  lastPiece.parentNode.removeChild(lastPiece);
  isBlackTurn = !isBlackTurn; // 切换回合
  message.innerHTML = isBlackTurn ? "黑子回合" : "白子回合";
});

这就是五子棋游戏的核心代码啦!当然,还可以在代码中添加一些界面元素、声音效果等,以增强用户体验。