简体   繁体   English

如何检查一个div是否每秒与另一个div重叠?

[英]How to check if a div overlaps with another div every second?

I am making a quick game about moving the player to dodge bullets, but I am having problems with how to detect if any bullet colided with the player.我正在制作一个关于移动玩家躲避子弹的快速游戏,但我遇到了如何检测是否有任何子弹与玩家碰撞的问题。 In game engines there would usually just exist eventlisteners for coliding of two objects, since I haven't found anything like that for webb development, I thought I could just use an infinite loop to check each bullet if it has collided with the player.在游戏引擎中,通常只存在用于碰撞两个对象的事件侦听器,因为我还没有找到类似 webb 开发的东西,我想我可以使用无限循环来检查每个子弹是否与玩家发生碰撞。

I can't do a while (true) loop, because it just crashes.我不能做一个while (true)循环,因为它只是崩溃。 I tried to make an interval in the spawn function of each bullets, but I couldn't figure out how to clear the interval after the bullet despawns.我试图在每个子弹的生成 function 中设置一个间隔,但我不知道如何在子弹消失后清除间隔。 And I have also tried to just make an interval that would loop through existing bullets at the moment and check if the bullet is coliding, but for some reason I get this error: Uncaught TypeError: bullets.forEach is not a function here is the code:而且我还尝试只设置一个当前循环通过现有子弹的间隔并检查子弹是否正在碰撞,但由于某种原因我收到此错误: Uncaught TypeError: bullets.forEach is not a function这是代码:


function checkOverlap(){
    let bullets = document.getElementsByClassName("bullet");
    if (bullets.length > 0){
        bullets.forEach(bullet => {
            let overlap = !(bullet.right < player.left || 
                    bullet.left > player.right || 
                    bullet.bottom < player.top || 
                    bullet.top > player.bottom)
            if (overlap){
                console.log("overlap");
            }
        });
    }
}
setInterval(checkOverlap, 1000);

I also wonder if this is even posible to detect the overlapping this way.我也想知道这是否甚至可以通过这种方式检测重叠。 Since I am using transition and left, top, right, down css properties to move my bullets, would it detect or do I need to use something else?由于我正在使用transitionleft, top, right, down css 属性来移动我的子弹,它会检测到还是我需要使用其他东西?

You can't access forEach because document.getElementsByClassName doesn't return an Array - it returns a NodeList which behaves somewhat like an Array , but deviates in other ways - for one thing its prototype has no forEach method.您无法访问forEach因为document.getElementsByClassName不返回Array - 它返回的NodeList的行为有点像Array ,但在其他方面有所不同 - 一方面,它的原型没有forEach方法。

You can easily convert to an Array by doing the following instead:您可以通过执行以下操作轻松转换为Array

let bullets = [ ...document.getElementsByClassName('bullet') ];

As far as collision goes, I recommend you use getBoundingClientRect (I often confused its spelling for getClientBoundingRect , now I remind myself that B preceeds C :D).至于碰撞,我建议你使用getBoundingClientRect (我经常混淆它的拼写getClientBoundingRect ,现在我提醒自己B C :D)。 This returns the absolute geometry of an html element, taking everything into account:这将返回 html 元素的绝对几何形状,并考虑所有因素:

 let doCollide = (player, bullet) => { let playerBound = player.getBoundingClientRect(); let bulletBound = bullet.getBoundingClientRect(); // (px, py) and (bx, by) represent the center of the player and bullet let px = playerBound.left + playerBound.width * 0.5; let py = playerBound.top + playerBound.height * 0.5; let bx = bulletBound.left + bulletBound.width * 0.5; let by = bulletBound.top + bulletBound.height * 0.5; let wOff = (playerBound.width + bulletBound.width) * 0.5; let hOff = (playerBound.height + bulletBound.height) * 0.5; // Collision occurs when bullet and player are separated on neither x nor y axes return Math.abs(px - bx) < wOff && Math.abs(py - by) < hOff; } let player = document.getElementsByClassName('player')[0]; let bullet = document.getElementsByClassName('bullet')[0]; let testFn = () => { player.style.left = `${Math.floor(Math.random() * 300)}px`; player.style.top = `${Math.floor(Math.random() * 150)}px`; bullet.style.left = `${Math.floor(Math.random() * 300)}px`; bullet.style.top = `${Math.floor(Math.random() * 150)}px`; if (doCollide(player, bullet)) { player.classList.add('coll'); bullet.classList.add('coll'); } else { player.classList.remove('coll'); bullet.classList.remove('coll'); } }; setInterval(testFn, 1500); testFn();
 html, body { position: relative; width: 100%; height: 100%; overflow: hidden; padding: 0; margin: 0; }.player, .bullet { position: absolute; }.player { width: 150px; height: 150px; box-shadow: inset 0 0 0 4px rgba(0, 150, 0, 1); }.bullet { width: 60px; height: 90px; box-shadow: inset 0 0 0 4px rgba(0, 210, 0, 1); }.player.coll { box-shadow: inset 0 0 0 4px rgba(200, 0, 0, 1); }.bullet.coll { box-shadow: inset 0 0 0 4px rgba(255, 0, 0, 1); }
 <div class="player"></div> <div class="bullet"></div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM