当玩家在 Tic Tac Toe 游戏中点击时,HTML img.src 和 img.style.display 不会更新

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

当我在代码中遇到一个错误时,我正在制作我的第一个 HTML/CSS/JS 项目,该错误涉及重置游戏后重新使用玩家输入的功能。

const greenO = "https://www.freeiconspng.com/uploads/green-circle-png-10.png"
const redX = "https://pnghq.com/wp-content/uploads/pnghq.com-download-red-cross-mark-download-png-hq-png-image.png"

const slots = document.getElementsByClassName("slots")
const slotImages = document.getElementsByClassName("slot-images")

let playerClickAvailable = true
let computerMoveAvailable = false

for (let i = 0; i <= 8; i++) {
  slots[i].addEventListener("click", function() {
    playerClick(i)
  })
}

function playerClick(i) {
  console.log("playerClick fired with (" + i + ")")
  console.log("player move available: " + playerClickAvailable)
  console.log("computer move available: " + computerMoveAvailable)
  console.log("playerClick fired in slot with img.src " + slotImages[i].src)
  console.log("playerClick fired in slot with img.style.display " + slotImages[i].style.display)

  if (playerClickAvailable) {
    const img = slotImages[i]
    if (img.src === "") {
      img.src = greenO
      img.style.display = "block"

      playerClickAvailable = false
      computerMoveAvailable = true

      if (checkWin() === undefined) {
        setTimeout(computerMove, 750);
      }
    }
  }
}

function computerMove() {
  console.log("player move available: " + playerClickAvailable)
  console.log("computer move available: " + computerMoveAvailable)

  if (computerMoveAvailable) {
    let img = undefined

    let occupiedCount = 0
    for (let i = 0; i <= 8; i++) {
      if (slotImages[i].src === "") {
        console.log("breaked after " + (i + 1) + " iteration(s)")
        break
      } else {
        occupiedCount += 1
      }
    }

    if (occupiedCount === 9) {
      console.log("tie")
      document.getElementById("reset").style.display = "block"
      return
    }

    while (true) {
      const i = Math.floor(Math.random() * 9)
      img = slotImages[i]
      if (img.src == "") {
        break
      }
    }

    img.src = redX
    img.style.display = "block"

    playerClickAvailable = true
    computerMoveAvailable = false

    checkWin()
  }
}

function giveWin(slot) {
  function blockMoves() {
    playerClickAvailable = false
    computerMoveAvailable = false
  }

  const reset = document.getElementById("reset")
  if (slot === greenO) {
    console.log("player won")
    reset.style.display = "block"
    blockMoves()
    return "player"
  } else if (slot === redX) {
    console.log("computer won")
    reset.style.display = "block"
    blockMoves()
    return "computer"
  }
}

function checkWin() {
  const first = slotImages[0].src
  const second = slotImages[1].src
  const third = slotImages[2].src
  const fourth = slotImages[3].src
  const fifth = slotImages[4].src
  const sixth = slotImages[5].src
  const seventh = slotImages[6].src
  const eighth = slotImages[7].src
  const ninth = slotImages[8].src

  if (
    (first === second && first === third) ||
    (first === fourth && first === seventh) ||
    (first === fifth && first === ninth)
  ) {
    giveWin(first)
  } else if (
    second === fifth && second === eighth
  ) {
    giveWin(second)
  } else if (
    (third === sixth && third === ninth) ||
    (third === fifth && third === seventh)
  ) {
    giveWin(third)
  } else if (
    fourth === fifth && fourth === sixth
  ) {
    giveWin(fourth)
  } else if (
    seventh === eighth && seventh === ninth
  ) {
    giveWin(seventh)
  }
}

function reset() {
  for (let i = 0; i <= 8; i++) {
    const img = slotImages[i]
    img.src = ""
    img.style.display = "none"
  }

  document.getElementById("reset").style.display = "none"

  playerClickAvailable = true
  computerMoveAvailable = false

  console.log("reseted")
}
body {
  min-height: 800;
  min-width: 800;
}

.center-flex {
  display: flex;
  justify-content: center;
}

#main-container {
  width: 600px;
  height: 600px;
  display: grid;
  grid-template: repeat(3, 1fr) / repeat(3, 1fr);
  gap: 15px;
  margin-bottom: 100px;
}

.slots {
  display: flex;
  justify-content: center;
  align-items: center;
  border-radius: 10%;
  padding: 15px;
  border: 10px solid rgb(71, 71, 71);
  background-color: cadetblue;
}

.slot-images {
  width: 100%;
  height: 100%;
  display: none;
}

#reset {
  width: 200px;
  height: 75px;
  display: none;
  border: 3px solid black;
  font-size: 50px;
  border-radius: 15px;
}

#reset-container {
  display: flex;
  justify-content: center;
}

#game-container {
  display: flex;
  justify-content: center;
  align-items: center;
}
<div id="game-container">
  <div id="main-container">
    <button class="slots"><img class="slot-images"></button>
    <button class="slots"><img class="slot-images"></button>
    <button class="slots"><img class="slot-images"></button>
    <button class="slots"><img class="slot-images"></button>
    <button class="slots"><img class="slot-images"></button>
    <button class="slots"><img class="slot-images"></button>
    <button class="slots"><img class="slot-images"></button>
    <button class="slots"><img class="slot-images"></button>
    <button class="slots"><img class="slot-images"></button>
  </div>
</div>
<div id="reset-container">
  <button id="reset" onclick="reset()">Reset!</button>
</div>

我已经放置了许多console.log()语句来调试,一切似乎都是正确的,但是在reset()函数运行之后,当玩家点击时,img.src和img.style.display不会更新,并且所有过去的东西都会中断。

我尝试更新和预设值以查看是否有任何更改,但它不起作用,我可以修复它的唯一方法是这样做:

location.reload()

在reset()函数的末尾。 但我知道这是一个糟糕的方法,将来我想制作一个记分板等等......

javascript html button tic-tac-toe mouseclick-event
1个回答
0
投票

游戏重置后失败:

if (img.src === "")

因为这有一个你意想不到的副作用:

img.src = ""

当设置为这样的空字符串时,生成的 DOM 元素是:

<img src class="slot-images">

或者也许:

<img src="" class="slot-images">

浏览器会尽其所能悄悄地“更正”HTML,如果某个属性需要 URL,则“更正”会尝试推断有关该 URL 的信息。 例如,这允许存在相对路径。 它对 blank URL 的推断是使用 当前页面的 URL。

因此,重置后,任何时候您将空

src
""
进行比较都会失败,因为“空
src
”实际上是当前页面的URL,而不是空字符串。


按照与图像文件相同的模式,将另一个图像添加到某些默认图像中。 例如:

const empty = "https://i.sstatic.net/mwFzF.png";

将所有图像初始化为:

<img src="https://i.sstatic.net/mwFzF.png" class="slot-images">

并在整个逻辑中使用该值。 比如重置游戏时:

img.src = empty

并且在比较确定移动的值时:

if (img.src === empty)
© www.soinside.com 2019 - 2024. All rights reserved.