Простое обнаружение столкновений в 2 деления с анимацией CSS с использованием vanilla JS - PullRequest
3 голосов
/ 07 января 2020

Я пытаюсь создать супер простую игру в стиле Super Mario, используя HTML, CSS и JS.

Я не использую <canvas>, просто выстраиваю все это в простых делениях и получаю движение фона и персонажей с помощью CSS Анимаций.

Часть, в которой я сталкиваюсь с проблемами, - это обнаружение столкновений между персонажем и монстрами. По сути, я хочу, чтобы персонаж вообще касался монстра, игра окончена, и вы избегаете монстров, прыгая.

Я пробовал разные фрагменты JS для обнаружения коллизий в div, но проблема заключается в том, что код возвращает позиции состояния c X и Y для div, а не для каждого ключевого кадра в CSS анимация.

Выполняя некоторые раскопки, я нашел способ для кода отслеживать X и Y каждого ключевого кадра, добавив прослушиватель событий к моему монстру и символьным div:

    shadow1.addEventListener('animationiteration', function (event) {
       shadowDiv = this.getBoundingClientRect();
       console.log(shadowDiv);
    });

    cont.addEventListener('animationiteration', function (event) {
      charDiv = this.getBoundingClientRect();
      console.log(charDiv);
});

Вышеприведенное возвращает все позиции X и Y, поскольку анимация запускается в консоли как для монстра, так и для персонажа, но проблема, с которой я сталкиваюсь, заключается в том, что она возвращает ключевые кадры, только если она находится в области действия прослушивателя событий. Я пытался всеми способами добиться того же, чтобы это происходило в глобальной области видимости, но каждый раз, когда я это делаю, он возвращает значение undefined, и оттуда я в основном застрял. и не уверен, как двигаться вперед.

Любая помощь будет оценена!

Ниже приведен соответствующий код:

HTML

 <div id="char-container"></div>

 <div id="shadow-container-1"> </div>

 <div id="btn"> Jump! </div>


CSS

@keyframes rtol {
  0% { left: 800px; opacity: 1;}
  80% { opacity: 1;}
  85%{ opacity: 0.75;}
  90% { left: -220px; opacity: 0;}
  100% { left: -220px; opacity: 0;}
}

#shadow-container-1{
 width: 100px;
 height: 160px;
 position: absolute;
 display: block;
 bottom: 450px;
 left: 800px;
 opacity: 1;
 animation-name: rtol;
 animation-iteration-count: infinite;
 animation-direction: normal;
 animation-timing-function: linear;
 animation-fill-mode: backwards;

@keyframes jump {
    from { bottom: -50px;  left: 0px; }
    to { bottom: 400px; left: 150px; }
}


#char-container{
 width: 150px;
 height: 200px;
 position: relative;
 bottom: -50px;
}

JS

let btn = document.getElementById('btn');

let cont = document.getElementById('char-container');


btn.addEventListener('click', function(e){

   if(e.target = btn){
       cont.style.webkitAnimationPlayState = 'running';
       cont.style.webkitAnimation = 'jump 1.25s ease 2';
       cont.style.webkitAnimationDirection = 'alternate';
   }

});

cont.addEventListener("webkitAnimationEnd", function(e){

  cont.style.webkitAnimation = '';
});


let shadow1 = document.getElementById('shadow-container-1');

shadow1.style.webkitAnimationDuration = Math.floor(Math.random() * 15) + 3   + 's';

shadow1.addEventListener('animationiteration', function (event) {
      shadowDiv = this.getBoundingClientRect();
      console.log(shadowDiv);
});


cont.addEventListener('animationiteration', function (event) {
      charDiv = this.getBoundingClientRect();
      console.log(charDiv);
});
...