Jason
Jason

Reputation: 279

Track element position with JavaScript

I'm making a simple shooting game and my idea is to track both the bullet and the enemy and check if they eventually collide. I'm using the following code for the bullet movement:

function animateBullet(bullet) {
  let height = document.body.style.height;
   
  let distanceToTop = bullet.offsetTop - document.body.style.height;

  bullet.animate(
    [
      // keyframes
      { transform: `translateY(0px)` },
      { transform: `translateY(${-distanceToTop}px)` },
    ],
    {
      // timing options
      duration: 500,
      iterations: 1,
    }
  );
}

In order to check both the bullet and the enemy position I'm using this code (not clean yet):

function killEnemy(bullet) {
  let enemy = document.querySelectorAll(".enemy-player");

  let bulletLeft = bullet.offsetLeft;
  let bulletRight = bullet.offsetLeft + 5;
  let bulletTop = bullet.offsetTop;

  console.log("bullet left: " + bulletLeft);
  console.log("bullet right: " + bulletRight);
  console.log("bullet top: " + bulletTop);

  for (let i = 0; i < enemy.length; i++) {
    let enemyLeft = enemy[i].offsetLeft;
    let enemyRight = enemy[i].offsetLeft + 15;
    let enemyBottom = enemy[i].offsetTop + 15;

    console.log("enemy left: " + enemyLeft);
    console.log("enemy right: " + enemyRight);
    console.log("enemy bottom: " + enemyBottom);

    // not working!!!
    if (enemyBottom === bulletTop) {
      enemy[i].remove();
    }
  }
}

The problem is that this second function will get their position only at the moment the bullet is fired, so the enemy is destroyed only when the player is touching it, which is not ideal.

Question: how can I track their position the whole time from the moment the bullet is fired?

Extra question for the geniuses: the way I wrote the first function the bullet is slowing down the higher the player is located on the screen. How can I make the bullet travel at the same speed no matter the position of the player at the moment it's fired?

Big thanks!

Upvotes: 2

Views: 1618

Answers (1)

Pavlos Karalis
Pavlos Karalis

Reputation: 2966

You have to repeatedly call getBoundingClientRect to get an elements current location:

const red = document.getElementById("red");
const blue = document.getElementById("blue");

const interval = setInterval(()=> {
  if(red.getBoundingClientRect().right >= blue.getBoundingClientRect().left){
    console.log("Collision!");
    red.style.animationPlayState = "paused";
    blue.style.animationPlayState = "paused";
    clearInterval(interval);
  }
},0);
body {
  height: 100vh;
  width: 100vw;
  display: flex;
  justify-content: space-between;
  box-sizing: border-box; 
  margin: 0;
}


#red, #blue {
  width: 100px;
  height: 100px; 
  border-radius: 100px;
}


#red {
  background-color: red; 
  animation-name: right;
  animation-duration: 4s;
  animation-timing-function: linear; 
}

#blue{
  background-color: blue;
  animation-name: left;
  animation-duration: 2s;
  animation-timing-function: linear; 
}

@keyframes left {
  from {transform: translateX(0)}
  to {transform: translateX(calc(-100vw + 100px))}
}

@keyframes right {
  from {transform: translateX(0)}
  to {transform: translateX(calc(100vw - 100px))}
}
<div id="red"></div>
<div id="blue"></div>

Upvotes: 2

Related Questions