我将非常感谢任何帮助,尝试用 JS 编写《太空入侵者》,设法在函数中移动外星人,以在间隔中左右移动棋盘,激光射击也在另一个间隔中将其向上移动。 问题是,有时当激光击中外星人移动的确切时间时,它会射击两个外星人,而我屏幕上的外星人计数器与游戏中实际看到的不符,无法完成游戏,我按照全局变量外星人计数器,是间隔的问题,还是handleHit函数的问题,我不确定。
https://github.com/Farhan-Ganayim/Space-Invaders https://farhan-ganayim.github.io/Space-Invaders/
我成功射击了外星人,得分还不错,这种情况发生在与慢速外星人玩游戏并准确射击他们时,但是当将间隔设置为1秒时,有时会出现射击两个外星人的问题。
function handleAlienHit(pos) {
// clearInterval(laserInterval)
// updateCell(pos,null)
gGame.alienCount--
updateScore()
gHero.isShoot=false
}
function blinkLaser(pos) {
// var cellGameObject=gBoard[pos.i][pos.j].gameObject
updateCell(pos, LASER)
setTimeout(() => {
updateCell(pos, null)
}, 80)
}
您通过引用传递位置对象,就好像它具有值语义一样。
function blinkLaser(pos) {
updateCell(pos, LASER)
setTimeout(() => {
updateCell(pos, null) // <-- Oops! The properties of pos may have changed!
}, 80)
}
pos
是您在 shoot 函数 中定义的对象(在该代码中称为 laserPos
)。 在使用位置的所有情况下,您都可以重复使用同一个对象,但是您可以通过调用 laserPos.i--
修改其属性。
这意味着在您调用
pos
之后但在超时之前,可以更改 updateCell(pos, LASER)
的属性。 然后,由于 updateCell(pos, null)
指的是唯一的位置对象,但其属性已更改,因此您的 blinkLaser
函数无法正确更新屏幕。
您可以通过编写
updateCell({ ...pos }, null)
来制作位置对象的 浅拷贝 来解决此问题,以便清空您之前在 updateCell(pos, LASER)
的函数中更新的相同位置。