Как отобразить X на доске, созданной с помощью циклов for, нажав на квадрат - PullRequest
0 голосов
/ 02 мая 2020

Я новичок, поэтому, пожалуйста, будьте милостивы :) Я пытаюсь сделать игру ti c ta c toe с html, css и чистым JS. Я застрял при попытке отобразить символ «X» (или «O»), нажимая на квадрат на моей доске (я использовал для него петли, как раньше, для игры в тетрис). Я пытался прослушивать события, но не мог заставить его работать, вероятно, я делаю что-то не так: P Так или иначе, мой вопрос: как отобразить символ на доске, нажав на него?

<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>

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

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


//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();

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

//let the starting player be selected at random
const spot = board[r-1][c-1];

function setup() {
    let randomPlayer = Math.floor(Math.random() *2 );
    let currentPlayer = "";
    if (randomPlayer == 0){
        currentPlayer = player1;
        alert('Player 1 starts the game !')
    }else {
        currentPlayer = player2;
        alert('Player 2 starts the game !')
    };
}
function drawSymbol () {
    let x = w * r + w/2;
    let y = h * c + h/2;
    let xr = w/4;
    spot.addEventListener('click', (x, y, xr) => {
    line(x-xr, y-xr, x+xr, y+xr);
    line(x+xr, y-xr, x-xr, y+xr);
})
}


setup();
//Check if player clicked on the board 

//Place X

//Place O

ОБНОВЛЕННЫЙ КОД

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);
            drawSymbol(newRow, newCol)
        })  
    }




calculatePos();
}
setup();
// listens for clicks on the canvas to draw the symbol
function drawSymbol (newRow, newCol) {
    let x = w * newRow + w/2;
    let y = h * newCol + h/2;
    let xr = w/4;
    if(currentPlayer == players[0]) {
        canvas.addEventListener('click', () => {
            ctx.lineWidth = 5;
            ctx.strokeStyle = 'black';
            ctx.beginPath();
            ctx.moveTo(x-xr, y-xr);
            ctx.lineTo(x+xr, y+xr);
            ctx.moveTo(x+xr, y-xr);
            ctx.lineTo(x-xr, y+xr);
            ctx.stroke();
    }) 
    } else {
            canvas.addEventListener('click', () => {
                ctx.lineWidth = 5;
                ctx.strokeStyle = 'black';
                ctx.beginPath();
                ctx.arc(x , y, 40, 0, 2 * Math.PI);
                ctx.stroke();
    }
)}
}
drawSymbol(r, c);

Ответы [ 2 ]

1 голос
/ 03 мая 2020

Хорошо выглядит до сих пор! Один из способов достижения sh - это добавить прослушиватель событий ко всему элементу холста . Подходящее место для его добавления - функция setup; таким образом, как только доска настроена, ваш холст будет прослушивать щелчки.

Теперь, если весь холст прослушивает щелчки, вам потребуется способ определить, какой квадрат был нажат. Это не так уж сложно, но есть некоторые препятствия. Давайте попробуем определить это для «одномерной доски»:

"The board"
+---------+---------+---------+

Предположим, что где-то на ней происходит щелчок:

+---------+---------+---------+
             ^click
|------------| <-clickPos = the distance between the click and the edge of the board

Как мы можем определить, в какой ячейке она произошла? Если мы знаем размер каждой ячейки и местоположение клика, это можно сделать с помощью деления:

const clickedCell = Math.floor(clickPos / cellSize);

Мы полагаем это значение для получения интегрального значения (для 0 оно будет равно 0 первая ячейка, 1 для второй и т. д. c.).

Вот где появляется «гоча»: когда происходит событие щелчка, легко извлечь местоположение щелчка относительно страницы , но это не обязательно то, что вы хотите.

Вот новая «доска», которая отражает это:

|            +---------+---------+---------+
^ edge                    ^click
of page                   |
|-------------------------| <-this distance is easy to extract from the event
             |------------| <-this is the distance you want
|------------| <-this is the distance between the edge of the board and the edge of the page

Как показывает диаграмма, позиция щелчка что нас волнует, на самом деле не тот, который записан на мероприятии. Чтобы определить это, нам нужно вычесть позицию щелчка из позиции левого края доски.

Вот как это выглядит в JavaScript:

canvas.addEventListener('mouseup', event => {
  const { left, top } = canvas.getBoundingClientRect();
  //      ^^^^  ^^^ These give us the position of the board relative to the page
  const mouseX = event.clientX - left;
  const mouseY = event.clientY - top;
  //                   ^^^^^^^ These give us the position of the click relative to the page

  const row = Math.floor(mouseY / sq);
  const col = Math.floor(mouseX / sq);

  // Now draw your "X" or "O" here, using the `row` and `col` values
  // calculated above to determine where to place it
});

Напоминаем, что вам нужно добавить этот прослушиватель только один раз; как только он будет добавлен, он будет вызывать функцию, которую мы предоставили каждый раз, когда происходит щелчок. Возможно, имеет смысл разделить работу по вычислению позиции на отдельную функцию и т. Д. c. но вы поймете это как вы go. Надеюсь это поможет; так держать!

0 голосов
/ 03 мая 2020

Вы, кажется, никогда не добавляете слушателя событий на сам холст? Из такого прослушивателя событий вы можете получить координаты X и Y щелчка, чтобы определить, какая ячейка была нажата. Если эта ячейка свободна, нарисуйте символ для текущего игрока.

Так что вам нужно, чтобы ваш drawSymbol принимал информацию о том, в какую ячейку рисовать.

Вы создаете переменную spot, которую я не понимаю, что она делает, и внутри drawSymbol добавляете слушатель события, но это, вероятно, не элемент? А функция drawSymbol никогда не вызывается, поэтому код не выполняется, поэтому вы тоже не получите ошибку.

...