【问题标题】:Uncaught TypeError: Cannot read property 'classList/forEach' of undefined solution?未捕获的类型错误:无法读取未定义解决方案的属性“classList/forEach”?
【发布时间】:2020-09-28 14:42:23
【问题描述】:

我对编码还很陌生,正在尝试创建俄罗斯方块游戏。但是,我遇到了一些我不知道解决方案的错误。在 javascript 中,我收到错误 Uncaught TypeError: Cannot read property 'classList/forEach' of undefined in两个单独的部分。

“forEach”的错误出现在“//draw/undraw tetros”,classList 的错误出现在代码底部的 classList.add('tetromino')。

如果有人知道我该如何解决这个问题,将不胜感激。 :)

document.addEventListener('DOMContentLoaded', () => {
document.querySelector('.grid');
let squares = Array.from(document.querySelectorAll('.grid div'));
const ScoreDisplay = document.querySelector('#score');
const StartBtn = document.querySelector('#start-button');
const width = 10;
let nextRandom = 0;

// The Tetrominoes//
const lTetromino = [
  [1, width+1, width*2+1, 2],
  [width, width+1, width+2, width*2+2],
  [1, width+1, width*2+1, width*2],
  [width, width*2, width*2+1, width*2+2]
  ]

const zTetromino = [
  [0, width, width+1, width*2+1],
  [width+1, width+2, width*2, width*2+1],
  [0, width, width+1, width*2+1],
  [width+1, width+2, width*2, width*2+1]
  ]

const tTetromino = [
 [1, width, width+1, width+2],
 [1, width+1, width+2, width*2+1],
 [width, width+1, width+2, width*2+1],
 [1, width+1, width*2+1]
 ]

const oTetromino = [
 [0, 1, width, width+1],
 [0, 1, width, width+1],
 [0, 1, width, width+1],
 [0, 1, width, width+1]
 ]

const iTetromino = [
 [1, width+1, width*2+1, width*3+1],
 [width, width+1, width+2, width+3],
 [1, width+1, width*2+1, width*3+1],
 [width, width+1, width+2, width+3]
]

const theTetrominoes = [lTetromino, zTetromino, tTetromino, oTetromino, iTetromino]

let currentPosition = 4
let currentRotation = 0

//randomly select a tetromino and its first rotation
let random = Math.floor(Math.random()*theTetrominoes.length)
let current = theTetrominoes[random][0]

// draw tetromino
function draw() {
  current.forEach(index => {
    squares[currentPosition + index].classList.add('tetromino')

})
}

//undraw the Tetrominoe
function undraw() {
  current.forEach(index => {
   squares[currentPosition + index].classList.remove('tetromino')

})
}

//make the tetromino move down every second
timerId = setInterval(moveDown, 1000)

//assign funtion to keycodes
function control(e) {
  if(e.keyCode === 37) {
    moveLeft()
  } else if (e.keyCode === 38) {
    rotate()
  } else if (e.keyCode === 39) {
    moveRight()
  } else if (e.keyCode === 40) {
    moveDown()
  }
}

document.addEventListener('keyup', control)

//move down function
function moveDown() {
  undraw()
  currentPosition += width
  draw()
  freeze()
}

//freeze
function freeze() {
  if(current.some(index => squares[currentPosition + index + width].classList
  .contains('taken'))) {
    current.forEach(index => squares[currentPosition + index].classList.add('taken'))
    //start a new tetro falling
    random = nextRandom
    nextRandom = Math.floor(Math.random() * theTetrominoes.length)
    current = theTetrominoes[random][currentRotation]
    currentPosition = 4
    draw()
    displayShape()
  }
}

//move the tetro left, unless is at the edge or there is a blockage
  function moveLeft() {
  undraw()
  const isAtLeftEdge = current.some(index => (currentPosition + index) % width === 0)

  if(!isAtLeftEdge) currentPosition -=1

  if(current.some(index => squares[currentPosition + index].classList.contains('taken'))) {
    currentPosition +=1
}

draw()
}

//move the tetro right, unless is at the edge or there is a blockage
  function moveRight() {
  undraw()
  const isAtRightEdge = current.some(index => (currentPosition + index) % width
  === width -1)

  if(!isAtRightEdge) currentPosition +=1

  if(current.some(index => squares[currentPosition + index].classList.contains('taken'))) {
    currentPosition -=1
  }
  draw()
}

//rotate retro
function rotate() {
  undraw()
  currentRotation ++
  if(currentRotation === current.length) { //if the current rotation gets to 4, make it go back to 0
    currentRotation = 0
  }
  current = theTetrominoes[random][currentRotation]
  draw()
}

//show up-next tetro in mini-grid
const displaySquares = document.querySelectorAll('mini-grid div')
const displayWidth = 4
let displayIndex = 0

// the tetro without currentRotation
const upNextTetrominoes = [
  [1, displayWidth+1, displayWidth*2+1, 2], //lTetromino
  [0, displayWidth, displayWidth+1, displayWidth*2+1], //zTetromino
  [1, displayWidth, displayWidth+1, displayWidth+2], //tTetromino
  [0, 1, displayWidth, displayWidth+1], //oTetromino
  [1, displayWidth+1, displayWidth*2+1, displayWidth*3+1] //iTetromino
]

//display the shape in the mini-grid display
function displayShape() {
  //remove any trace of a tetromino form the entire grid
  displaySquares.forEach(square => {
    square.classList.remove('tetromino')
  })
  upNextTetrominoes[nextRandom].forEach( index => {
    displaySquares[displayIndex + index].classList.add('tetromino')
  })
}


})

【问题讨论】:

标签: javascript


【解决方案1】:

Please provide minimal reproducible example。但是,以下提供的代码似乎存在问题

问题 1

“forEach”的错误出现在“//draw/undraw tetros”

这是因为您将数组嵌套在 3 级,但试图得到这样的 let current = theTetrominoes[random][0],这意味着您正在尝试访问不是的二维数组。

解决方案

尝试将其设为 2d 数组或像 3d 数组一样访问它:

theTetrominoes[random][0][desired_index]

问题 2

classList 的错误出现在代码底部的 classList.add('tetromino')

您将index 作为第一个参数传递给forEach(),这实际上是一个实际存储的项目。

解决方案

你应该这样做:

current.forEach((item, index) => {
      console.log(index)
    });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-24
    • 1970-01-01
    • 2015-01-14
    • 2022-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多