有时在《太空侵略者 JS》中,当射击击中外星人时,我会同时射击两个外星人

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

我将非常感谢任何帮助,尝试用 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)
}
javascript intervals 2d-games
1个回答
0
投票

您通过引用传递位置对象,就好像它具有值语义一样。

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)
的函数中更新的相同位置。

© www.soinside.com 2019 - 2024. All rights reserved.