未捕获的类型错误:无法读取未定义解决方案的属性"classList/forEach"?



我对编码相当陌生,正在尝试创建一个俄罗斯方块游戏。但是,我遇到了一些不知道解决方案的错误。在javascript中,我收到错误Uncatch TypeError:无法读取两个单独部分中未定义的属性'classList/forEach'。

"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')
})
}

})

请提供最少的可重现示例。但是,使用下面提供的代码似乎存在问题

问题1

"forEach"的错误出现在"//draw/undraw tetros"中

这是因为您在 3 级嵌套数组,但试图像这样let current = theTetrominoes[random][0]这意味着您正在尝试访问 2d 数组,但事实并非如此。

溶液

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

theTetrominoes[random][0][desired_index]

问题2

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

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

溶液

你应该做这样的事情:

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

相关内容

最新更新