使用JS制作井字游戏

using JS to make tic tac toe

我用 JS 做了一个井字游戏,但是它有一些问题我的代码是:

let x = [];
let o = [];
let xTurn = false;
let winPat = [
  ['00', '10', '20'],
  ['01', '11', '21'],
  ['02', '12', '22'],
  ['00', '01', '02'],
  ['10', '11', '12'],
  ['20', '21', '22'],
  ['00', '11', '22'],
  ['02', '11', '20']
];

const tableR = document.getElementsByClassName('tableR');
const button = document.getElementById('btn')

for (let i = 0; i <= 2; i++) {
  for (let j = 0; j <= 2; j++) {
    let newElement = document.createElement('td');
    tableR.item(i).appendChild(newElement);
    newElement.addEventListener('click', () => {
      if (elementIsEmpty(newElement)) {
        const img = document.createElement('img');
        if (xTurn) {
          img.src = 'https://www.google.com/url?sa=i&url=https%3A%2F%2Fcommons.wikimedia.org%2Fwiki%2FFile%3ARed_X.svg&psig=AOvVaw1B-fppvlN2x5oSCGllnXGc&ust=1634565535566000&source=images&cd=vfe&ved=0CAkQjRxqFwoTCMjbg6XN0fMCFQAAAAAdAAAAABAD';
          x.push(String(i) + String(j))
        } else {
          img.src = 'https://www.google.com/imgres?imgurl=https%3A%2F%2Fupload.wikimedia.org%2Fwikipedia%2Fcommons%2Fthumb%2Fd%2Fd0%2FLetter_o.svg%2F407px-Letter_o.svg.png&imgrefurl=https%3A%2F%2Fcommons.wikimedia.org%2Fwiki%2FFile%3ALetter_o.svg&tbnid=p-B77Lz3DDttwM&vet=12ahUKEwizlYTWzdHzAhXMg9gFHTSaBJkQMygAegUIARDaAQ..i&docid=K2HPZsIMOu4d5M&w=407&h=768&q=pixture%20of%20o&ved=2ahUKEwizlYTWzdHzAhXMg9gFHTSaBJkQMygAegUIARDaAQ';
          o.push(String(i) + String(j))
        }
        newElement.append(img)
        checkWinOrDraw(xTurn)
        xTurn = !xTurn
      }
    })
  }
}

const td = document.getElementsByTagName('td')
button.addEventListener('click', () => {
  reset();
});

function elementIsEmpty(el) {
  return (/^(\s|&nbsp;)*$/.test(el.innerHTML));
}

function checkWinOrDraw(xTurn) {
  for (let i = 0; i < winPat.length; i++) {
    if (xTurn) {
      if (winPat[i].every(element => x.includes(element))) {
        alert('X wins')
        reset()
        return
      }
    } else {
      if (winPat[i].every(element => o.includes(element))) {
        alert('O wins')
        reset()
        return
      }
    }
  }

  for (let item of td) {
    if (elementIsEmpty(item))
      return
  }
  alert('Draw')
  reset()
}


function reset() {
  x = [];
  o = [];
  for (let item of td) {
    item.textContent = ''
  }
}
body {
  margin: 0px;
  background-color: #3c4552;
  color: aliceblue;
  text-align: center;
}

header {
  height: 75px;
  background-color: #1f1e1c;
  padding: 20px;
  font-size: large;
}

table {
  border-collapse: collapse;
  margin: 40px auto;
}

td {
  border: 7px solid black;
  height: 121px;
  width: 121px;
  cursor: pointer;
}

button {
  background-color: #1f1e1c;
  color: white;
  width: 25%;
  height: 50px;
  font-size: larger;
  border: black solid 2px;
  border-radius: 7px;
  cursor: pointer;
}

img {
  display: block;
  width: 100%;
  height: 100%;
}
<header>
  <h1>TicTacToe</h1>
</header>
<main>
  <table>
    <tr class="tableR"></tr>
    <tr class="tableR"></tr>
    <tr class="tableR"></tr>
  </table>
</main>
<footer>
  <button id="btn">RESET</button>
</footer>

我的问题是当游戏结束时,说 X 赢了,图像没有在屏幕上呈现,并且调用了 alert()。我在谷歌上搜索了很多,但没有找到解决方案。

细节和清晰度: 游戏结束时图像不会呈现在屏幕上。在你的电脑上试试看。 alert() 在图像出现在游戏中之前被调用,这会导致糟糕的用户体验。因此我需要一个解决方案。

此处您的 append() 函数无法完成图像加载,您的 checkWinOrDraw() 函数被调用,这就是发生这种情况的原因。

请尝试使用下面的代码,一旦图像加载或失败,我将调用 checkWinOrDraw()

for (let i = 0; i <= 2; i++) {
  for (let j = 0; j <= 2; j++) {
    let newElement = document.createElement('td');
    tableR.item(i).appendChild(newElement);
    newElement.addEventListener('click', () => {
      if (elementIsEmpty(newElement)) {
        const img = document.createElement('img');
        if (xTurn) {
          img.src =  'https://dummyimage.com/20x20/3a4ca6/fff';
          x.push(String(i) + String(j))
        } else {
          img.src = 'https://dummyimage.com/30x30/fff/fff';
          o.push(String(i) + String(j))
        }
        console.log(xTurn)
         xTurn = !xTurn
        img.addEventListener('load', checkWinOrDraw)
  img.addEventListener('error', checkWinOrDraw)
        newElement.appendChild(img)
      }
    })
  }
}

function checkWinOrDraw(e,xTurn) {
        
  //console.log('checking',xTurn)
  for (let i = 0; i < winPat.length; i++) {
    if (xTurn) {
      if (winPat[i].every(element => x.includes(element))) {
        alert('X wins')
        reset()
        return
      }
    } else {
      if (winPat[i].every(element => o.includes(element))) {
        alert('O wins')
        reset()
        return
      }
    }
  }

  for (let item of td) {
    if (elementIsEmpty(item))
      return
  }
  alert('Draw')
  reset()
}