In the previous three sections, we have laid the foundation for the knowledge of canvas. In this section, we will “land” and realize a small game of backgammon

Before we start, let’s think about what to do:

  1. First we’re going to draw a checkerboard
  2. And then you have black and white
  3. Judge whether the current position has been placed and whether there are five pieces in the direction of the “meter” type. If the conditions are met, the current player wins

To get started, prepare a Canvas container and a refresh button to reopen, and prepare a result area to display a prompt message

<canvas id="canvas" width="200px" height="200px"></canvas>
<p class="result"></p>
<button onclick="LoadPanel (400, 400,30,13)">The refresh</button>
Copy the code

The board

First let’s draw the checkerboard, this is easy, just loop the line, we put all the operations in a function, so we can start again

/ * * *@param W checkerboard width *@param H checkerboard height *@param Cs grid size *@param Ps chess radius */
function loadPanel(w, h, cs, ps) {
  let i, j, k;

  //1) Draw the chessboard. The edges should be separated from the radius of the pieces
  cs = cs || 16;// Default grid width and height
  ps = ps || 4;// The radius of the piece
  h = h || w;// Height equals width by default

  let el = document.getElementById('canvas');
  el.setAttribute('width', w + 'px');
  el.setAttribute('height', h + 'px');
  let context = el.getContext("2d");
  // Compute checkerboard division, round down
  let splitX = ~~((w - 2 * ps) / cs), 
      splitY = ~~((h - 2 * ps) / cs);

  // loop line
  context.translate(ps, ps);
  context.beginPath();
  context.strokeStyle = '# 000';
  / / vertical line
  for (i = 0; i < splitX + 1; i++) {
    context.moveTo(cs * i, 0);
    context.lineTo(cs * i, splitY * cs);
    context.stroke();
  }
  / / horizontal line
  for (j = 0; j < splitY + 1; j++) {
    context.moveTo(0, cs * j);
    context.lineTo(splitX * cs, cs * j);
    context.stroke();
  }
  context.closePath();
}

// Draw the checkerboard
loadPanel(400.400.30.13);
Copy the code

The function of ~~ is to round down. You can convert a floating point type to an integer or a string number, but the result cannot be 0

Now open your browser and see what it looks like

pieces

It is not difficult to draw the chess pieces, that is, draw a circle, fill the black with black, fill the white with white, and then stroke the edge. Related API has been introduced before, we first draw two static chess pieces on the board to observe the effect

context.beginPath()
context.arc(cs * 0, cs * 0, ps, 2 * Math.PI, false);
context.fillStyle = '#fefefe'
context.fill()
context.stroke();
context.closePath()

context.beginPath()
context.arc(cs * 1, cs * 0, ps, 2 * Math.PI, false);
context.fillStyle = '# 000'
context.fill()
context.stroke();
context.closePath()
Copy the code

The effect is not bad, but it needs mouse click when playing chess. The rendering of the chess pieces here needs mouse click event to trigger. Next, we need to add mouse click event to canvas.

let user = 0, colors = ['# 000'.'#fefefe'];
el.addEventListener('click'.function (e) {
  let x = e.offsetX,
    y = e.offsetY,
    // Calculate the subrange
    rx = ~~((x - ps) / cs) + (((x - ps) % cs <= cs / 2)?0 : 1),
    ry = ~~((y - ps) / cs) + (((y - ps) % cs <= cs / 2)?0 : 1);

  context.beginPath();
  context.arc(cs * rx, cs * ry, ps, 2 * Math.PI, false);
  context.fillStyle = colors[user];
  context.strokeStyle = '# 000';
  user ? user = 0 : user = 1;// Switch the holder
  context.fill();
  context.stroke();
  context.closePath();
})
Copy the code

Now we’re about 50 percent done

The winner determination

Now do the step after the event, determine whether there are 5 pieces of the same color on the direction of the word “meters”, we will consider the answer train of thought, you do not look down first, consider your own ideas first

All right, now, whether you want to think about it or not, let me give you the general idea, first of all, define an object to store the drop cases, and it looks something like this

{
  1-1 ' ': 0.'2': 1
}
// key is the checkerboard position and value is the identity
Copy the code

Then use [0,1], [1, 0], [1, -1] respectively to represent up and down, left and right, oblique upward, oblique downward four directions, later take these directions respectively to traverse, the principle is roughly like this

For (let I = 1; i<= 4 ; I++) {}, with 0 and 1 times I respectively, and then combined with the current click x or y coordinates of the unknown, are able to traverse, because what I either take a zero is zero, so the x coordinates will not change, then y will traverse the above four, if all of the four is the current players, the determination to win, but if they don’t to go to the opposite direction, Loop for (let I = -1; i>= -4 ; I –) {}, repeat the step in another direction if the current loop ends without a victory

After calculating the coordinates, search for the winner in the object where the winner is stored. If it is the current winner, the game ends if the traversal ends and the winning condition is met

let user = 0, colors = ['# 000'.'#fefefe'];
let chks = [[1.0], [0.1], [1.1], [1, -1]].// Four directions
let pieces = {}; // Record the player's position
let successNum = 5;// Win chess criteria
let resultEl = document.querySelector('.result');

el.addEventListener('click'.function (e) {
  let x = e.offsetX,
    y = e.offsetY,
    // Calculate the subrange
    rx = ~~((x - ps) / cs) + (((x - ps) % cs <= cs / 2)?0 : 1),
    ry = ~~((y - ps) / cs) + (((y - ps) % cs <= cs / 2)?0 : 1);

  context.beginPath();
  context.arc(cs * rx, cs * ry, ps, 2 * Math.PI, false);
  context.fillStyle = colors[user];
  context.strokeStyle = '# 000';
  user ? user = 0 : user = 1;// Switch the holder
  context.fill();
  context.stroke();
  context.closePath();


  piece = pieces[rx + The '-' + ry] = user;

  for (j = 0; j < chks.length; j++) {
    let num = 1, chk = chks[j];
    for (i = 1; i <= 4; i++) {
      if (pieces[(rx + chk[0] * i) + The '-' + (ry + chk[1] * i)] == piece) {
        num++
      } else {
        for (i = -1; i >= -4; i--) {
          if (pieces[(rx + chk[0] * i) + The '-' + (ry + chk[1] * i)] == piece) {
            num++
          }
        }
        break}}if (num == successNum) {
      status = false
      resultEl.innerHTML = ['white'.'black'][user] + 'party won';
      break; }}})Copy the code

And then we’re done

But there are still a lot of logic problems that have not been solved, the game after the end of the limit can not continue to hit the child, click the position if there has been a child can not continue to hit the child and so on these as homework for you, in fact, it is not difficult, think about it

My final result is as follows

This article is part of the “Gold Nuggets For Free!” Event, click to view details of the event