I'm making a simple Space Invaders Clone in Web and ran into an issue. The code works well so far with the exception of the collision system. I need to destroy an enemy every time that the player's bullet hits it. In order to make it, I'm grabbing the x and y coordinates of both the enemies' div and the bullet's div. The issue appears on the values comparison: apparently getBoundingClientRect() grabs the x and y coordinates from within the element excluding its real size. Hence, according to my code, only when the bullet is perfectly inside the enemy that things would trigger. Is there a better way of doing it? How so?
Thanks in advance.
const shoot = (x) => {
//Creates bullet
const main = document.getElementById("main");
const div_bullet = document.createElement("div");
//Appends child
main.appendChild(div_bullet);
//Sets position
div_bullet.style.top = "340px";
div_bullet.style.left = x + "px";
//Gives it a class
div_bullet.classList.add("div_bullet");
div_bullet.setAttribute("id", "bullet");
//Deletes bullet
setTimeout(() => {
div_bullet.remove();
}, 1000);
};
const load_game = () => {
//Adding movement to the spaceship
const space_ship = document.getElementById("space_ship");
let x = 375;
window.addEventListener("keydown", (e) => {
switch (e.key) {
case "ArrowLeft":
if (x <= 15) break;
x = x - 10;
space_ship.style.left = x + "px";
break;
case "ArrowRight":
if (x >= 725) break;
x = x + 10;
space_ship.style.left = x + "px";
break;
case "ArrowUp":
if (document.getElementsByClassName("div_bullet").length === 0)
shoot(x + 20);
break;
default:
break;
}
});
};
const collision_system = () => {
setInterval(() => {
//Checks if any enemy was hit
const e1 = document.getElementById("e1");
const e2 = document.getElementById("e2");
const e3 = document.getElementById("e3");
const e4 = document.getElementById("e4");
const e5 = document.getElementById("e5");
const enemies_position = [{
x: e1.getBoundingClientRect().x,
y: e1.getBoundingClientRect().y
},
{
x: e2.getBoundingClientRect().x,
y: e2.getBoundingClientRect().y
},
{
x: e3.getBoundingClientRect().x,
y: e3.getBoundingClientRect().y
},
{
x: e4.getBoundingClientRect().x,
y: e4.getBoundingClientRect().y
},
{
x: e5.getBoundingClientRect().x,
y: e5.getBoundingClientRect().y
},
];
if (document.getElementById("bullet")) {
const x_bullet = document
.getElementById("bullet")
.getBoundingClientRect().x;
const y_bullet = document
.getElementById("bullet")
.getBoundingClientRect().y;
console.log(
"X: " + enemies_position[0].x + "Y: " + enemies_position[0].y
);
console.log("X bullet: " + x_bullet + "Y bullet : " + y_bullet);
for (let i = 0; i < 5; i++) {
if (
enemies_position[i].x === x_bullet &&
enemies_position[i].y === y_bullet
)
alert("Shoot!");
}
}
}, 10);
};
document.addEventListener("DOMContentLoaded", () => {
load_game();
collision_system();
});
* {
padding: 0px;
margin: 0px;
}
body {
background-color: black;
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.main {
width: 800px;
height: 500px;
border: 2px white solid;
border-radius: 10px;
}
@keyframes enemies_move {
from {
left: 80px;
}
to {
left: -80px;
}
}
.enemies {
margin-top: 20px;
position: fixed;
width: 800px;
height: 50px;
display: flex;
justify-content: space-evenly;
}
.enemies div {
position: relative;
width: 50px;
height: 50px;
background-color: orange;
animation: enemies_move 4s alternate infinite;
}
.barriers {
width: 800px;
height: 20px;
position: fixed;
top: 460px;
display: flex;
justify-content: space-evenly;
}
.barriers div {
width: 100px;
height: 20px;
background-color: white;
}
.space_ship {
width: 50px;
height: 50px;
border: 2px white solid;
position: relative;
top: 440px;
left: 375px;
}
@keyframes shoot_bullet {
from {
top: 340px;
}
to {
top: -50px;
}
}
.div_bullet {
left: 17px;
width: 15px;
height: 40px;
background-color: white;
position: relative;
animation: shoot_bullet 1s;
}
<div id="main" class="main">
<div class="enemies">
<div id="e1"></div>
<div id="e2"></div>
<div id="e3"></div>
<div id="e4"></div>
<div id="e5"></div>
</div>
<div class="barriers">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div id="space_ship" class="space_ship"></div>
</div>