如何用纯JS在点击的单元格上绘制符号

问题描述 投票:1回答:1

我从昨天开始就一直在想这个问题,试了很多,但不知道如何在点击特定单元格时在黑板上画一个X,它总是在第一个单元格上画。我想如果我将calculatePos函数中的newRow和newCol作为参数传给drawSymbol函数中的ctx.lineTo,就可以解决这个问题,但我不知道如何访问它?HTML

<!DOCTYPE="html5">
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <link rel="stylesheet" href="tic-tac-toe.css">
    <title>TIC TAC TOE IN JS</title>
    <h1 class='header'>TIC TAC TOE in JS</h1>
  </head>
<body>
    <div class='canvas'>
        <canvas id="canvas" width='300px' height="300px"></canvas>
    </div>
    <div class='scores'>
        <div>Player 1 Wins: <span id="score-x">0</span></div>
        <div>Ties: <span id="score-tie">0</span> </div>
        <div>Player 2 Wins: <span id="score-o">0</span> </div>
    </div>

<script src="./tictactoe.js"></script>

</body>

JS

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');

//Variables
let row = 3;
let col = 3;
const vacant = "white";
let sq = 100;
let w = canvas.clientWidth/3;
let h = canvas.clientHeight/3;
let currentPlayer = "";

//players
const players = ['X', 'O']
const player1 = players[0];
const player2 = players[1];


//draw a square
function drawSquare(x, y, color) {
    ctx.fillStyle = color;
    ctx.fillRect(x*sq, y*sq, sq, sq);
    ctx.strokeStyle = 'black';
    ctx.strokeRect(x*sq, y*sq, sq, sq);
}

//Create board
let board = [ ];
for(let r = 0; r < row; r++){
    board[r] = [ ];
        for(let c = 0; c < col; c++) {
            board[r][c] = vacant;
        }
}
//Draw Board
function drawBoard() {
    for(r = 0; r < row; r++) {
        for(c = 0; c < col; c++){
            drawSquare(c, r, board[r][c]);
        }
    }
}
drawBoard();



// sets up the game
function setup() {

    //let the starting player be selected at random
    let randomPlayer = Math.floor(Math.random() *2 );
    if (randomPlayer == 0){
        currentPlayer = player1;
        alert('Player 1 starts the game !')
    }else {
        currentPlayer = player2;
        alert('Player 2 starts the game !')
    };





    function calculatePos () {
        // checks for click position
        canvas.addEventListener('click', event => {

            // get the position of the board relative to the page
            let {left, top} = canvas.getBoundingClientRect();

            // get the position of the click relative to the page
            let mouseX = event.clientX - left;
            let mouseY = event.clientY - top;

            // calculate which square is being clicked 
            let newRow = Math.floor(mouseY / sq);
            let newCol = Math.floor(mouseX / sq); 
            return(newRow, newCol)
        })  
    }
        // listens for clicks on the canvas to draw the symbol
        function drawSymbol (newRow, newCol) {
            let xr = w*0.95;
            if(currentPlayer == players[0]) {
                canvas.addEventListener('click', () => {
                    ctx.lineWidth = 5;
                    ctx.strokeStyle = 'black';
                    ctx.beginPath();
                    ctx.moveTo(newRow, newCol);
                    ctx.lineTo(newRow+xr,newCol+xr);
                    ctx.stroke();
                    ctx.beginPath();
                    ctx.moveTo(newRow+xr, newCol);
                    ctx.lineTo(newRow,newCol+xr);
                    ctx.stroke();
            }) 
            } else {
                    canvas.addEventListener('click', () => {
                        ctx.lineWidth = 5;
                        ctx.strokeStyle = 'black';
                        ctx.beginPath();
                        ctx.arc(col + (xr * 1.8), row + (xr * 1.8), 40, 0, 2 * Math.PI); // needs to be updated, don't worry about that
                        ctx.stroke();
            }
        )}
        }
        drawSymbol(row, col);



calculatePos();
}
setup();

javascript canvas drawing
1个回答
0
投票

下面是一个使用文本的方法 strokeText 我觉得这种方式比较简单

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
ctx.fillStyle = "white";
ctx.font = "80px monospace";

let row = col = 3;
let sq = 100;

function drawBoard() {
  for (r = 0; r < row; r++) {
    for (c = 0; c < col; c++) {
      ctx.fillRect(r * sq, c * sq, sq, sq);
      ctx.strokeRect(r * sq, c * sq, sq, sq);
    }
  }
}

function drawSymbol(event) {
  let rect = canvas.getBoundingClientRect();
  let row = Math.floor((event.clientX - rect.left) / sq);
  let col = Math.floor((event.clientY - rect.top) / sq);
  let text = Math.random() > 0.5 ? "O" : "X";

  ctx.beginPath();
  ctx.lineWidth = 5;
  ctx.strokeText(text, row * sq + 25, col * sq + 80);
  ctx.stroke();
}

canvas.addEventListener('click', drawSymbol, false)
drawBoard();
<body>
  <div class='canvas'>
    <canvas id="canvas" width='300px' height="300px"></canvas>
  </div>
</body>

当你在发布一个问题的代码时,你必须先把你的代码还原成一个最小的例子,像你提出的这样一个巨大的问题会让很多人连看都不敢看。

© www.soinside.com 2019 - 2024. All rights reserved.