Как отключить EventListener, после того как значение равно 0
Делаю небольшой учебный проект, и столкнулся с такой проблемой, что не знаю как убрать EvenListener после того как значение достигло 0, как это можно оптимально сделать?
let monster = document.getElementById("monster");
let healthBarValue = document.querySelector(".health-bar-value");
let waveNumber = document.getElementById("wave-number");
let waveValue = waveNumber.textContent;
let damage = "";
function waves() {
if (waveValue == 1) {
healthBarValue.innerHTML = 100;
let health = healthBarValue.textContent;
}
if (waveValue == 2) {
healthBarValue.innerHTML = 250;
let health = healthBarValue.textContent;
}
if (waveValue == 3) {
healthBarValue.innerHTML = 500;
let health = healthBarValue.textContent;
}
if (waveValue == 4) {
healthBarValue.innerHTML = 1000;
let health = healthBarValue.textContent;
}
if (waveValue == 5) {
healthBarValue.innerHTML = 1500;
let health = healthBarValue.textContent;
}
if (waveValue == 6) {
healthBarValue.innerHTML = 2000;
let health = healthBarValue.textContent;
}
if (waveValue == 7) {
healthBarValue.innerHTML = 2500;
let health = healthBarValue.textContent;
}
if (waveValue == 8) {
healthBarValue.innerHTML = 3000;
let health = healthBarValue.textContent;
}
if (waveValue == 9) {
healthBarValue.innerHTML = 4000;
let health = healthBarValue.textContent;
}
if (waveValue == 10) {
healthBarValue.innerHTML = 8000;
let health = healthBarValue.textContent;
}
if (waveValue == "MEGA-BOSS") {
healthBarValue.innerHTML = 16000;
let health = healthBarValue.textContent;
}
}
waves();
monster.addEventListener("click", (e) => {
damage = 10;
let health = healthBarValue.textContent;
healthBarValue.innerHTML = health - damage;
if (healthBarValue.textContent == 0) {
monster.innerHTML = "YOU WIN";
monster.removeEventListener("click", e);
}
});
@import url('https://fonts.googleapis.com/css2?family=Roboto+Condensed:wght@700&display=swap');
*,*::after,*::before{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body{
background-color: rgb(255, 223, 40);
background-image: url(image/Balls2.png);
font-family: 'Roboto Condensed', sans-serif;
}
.content{
display: flex;
align-items: center;
flex-direction: column;
width: 80%;
height: 100vh;
margin: auto;
}
.header{
font-size: clamp(40px,3.6458333333333335vw,100px);
margin-top: 10px;
user-select: none;
margin: auto;
}
.monster{
font-size: clamp(120px,11.458333333333334vw,320px);
margin-top: clamp(100px,11.625vw,500px);
user-select: none;
cursor: pointer;
}
.health-bar{
width: clamp(300px,31.25vw,900px);
height: clamp(40px,2.6041666666666665vw,70px);
margin-top: clamp(20px,2.0833333333333335vw,60px);
border: 5px solid black;
position: relative;
}
.next{
margin-top: clamp(30px,2.6041666666666665vw,70px);
width: clamp(300px,21.875vw,740px);
height: clamp(40px,3.125vw,80px);
background-color: blueviolet;
cursor: pointer;
font-family: 'Roboto Condensed', sans-serif;
transition: 0.2s;
font-size: clamp(20px,2.0833333333333335vw,60px);
}
.wave{
margin-top: 10px;
font-size: clamp(20px,2.0833333333333335vw,60px);
color: rgb(255, 255, 255);
user-select: none;
}
.next:hover, .shop:hover{
color: white;
background-color: darkmagenta;
}
.upper{
display: flex;
justify-content: center;
width: 100%;
}
.shop{
margin-left: 50px;
width: clamp(70px,8.25vw,170px);
height: 60px;
background-color: blueviolet;
border-radius: 5px;
font-size: 40px;
cursor: pointer;
margin-top: 10px;
transition: 0.2s;
font-family: 'Roboto Condensed', sans-serif;
}
.money{
user-select: none;
font-size: 40px;
margin-top: 10px;
margin-right: 50px;
}
.health-bar-fill{
height: 100%;
width: 100%;
background-color: rgb(255, 75, 75);
transition: width 0.5s;
}
.health-bar-value{
position: absolute;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
font-family: 'Roboto Condensed', sans-serif;
font-size: 35px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="styles.css" />
<title>Kill Mob</title>
</head>
<body>
<div class="content">
<div class="upper">
<button class="shop">Shop</button>
<h1 class="header">KILL IT!</h1>
<p class="money">Money:000</p>
</div>
<h2 class="wave">WAVE: <span id="wave-number">1</span></h2>
<div id="monster" class="monster">?</div>
<div class="health-bar">
<div class="health-bar-value">1K</div>
<div class="health-bar-fill"></div>
</div>
<button class="next">NEXT</button>
</div>
<script src="script.js"></script>
</body>
</html>
Ответы (2 шт):
Пожалуйста!
monster.addEventListener("click", fight);
function fight(e) {
damage = 10;
let health = healthBarValue.textContent;
healthBarValue.innerHTML = health - damage;
if (healthBarValue.textContent == 0) {
EndGame();
}
};
function EndGame() {
monster.innerHTML = "YOU WIN";
monster.removeEventListener("click", fight);
}
Если немного оптимизировать код, не идельно, но все же, то должно получиться что-то такое. Некоторые моменты я пояснил в комментариях, но если будут вопросы, задавайте.
let monster = document.getElementById("monster");
let healthBarValue = document.querySelector(".health-bar-value");
let waveNumber = document.getElementById("wave-number");
let waveValue = waveNumber.textContent;
let damage = 10;
function removeMonsterClickHandler() { // функция, которая убирает EventListener с обрабочиком monsterClickHandler
monster.removeEventListener("click", monsterClickHandler, true);
}
function monsterClickHandler(e) { // создадим отельно обработчик клика
this.health-= damage; // this - это monster
healthBarValue.innerHTML = this.health;
if (this.health <= 0) { // Вдруг damage будет больше, чем оствшееся хп
this.innerHTML = "YOU WIN";
removeMonsterClickHandler(); // Убираем EventListener
}
}
/**
* Объект с волнами
* Ключ - номер волны
* Значение - здоровье монстра
*/
const wavesMap = {
1: 100,
2: 250,
3: 500,
4: 1000,
5: 1500,
6: 2000,
7: 2500,
8: 3000,
9: 4000,
10: 8000,
'MEGA-BOSS': 16000,
}
function waves() {
for (let wave in wavesMap) { // Перебираем объект с волнами в цикле
if (waveValue !== wave) continue; // Если ключ не равен номеру текущей волны, идем дальше
monster.health = wavesMap[wave]; // дадим монстру свойство health для удобства
healthBarValue.innerHTML = monster.health; // покажем health мостра в хелсбаре
break; // Выходим из цикла
}
}
waves();
monster.addEventListener("click", monsterClickHandler, true);
- Тут можно почитать про циклы. Чтобы не было такого нагромождения ветвлений с
if. Так же полезно почитать про конструкцию switch по той же причине. - Тут конкретно про for...in.
Если не понятно, что такое this в функции monsterClickHandler() и откуда оно взялось, то - это свойство контекста, являющееся ссылкой на объект, в нашем случае monster. Можете почитать о контексте и this на learn.javascript.ru.
UPD
Мне нечего было делать и я тут накатал свою версию вашего кликера. HTML и CSS почти не менял, хотя хотел. Там все уровни, покупки апгрейдов нет, поэтому показатель урона всегда равен 10, но я надеюсь, вы с этим разберетесь сами. После победы над боссом игра начнется с начала без сброса заработанных очков, типа NG+. Сделал рабочими хелсбар, очки, анимации ударов и смерти врага.
Забирайте, разбирайте: Исходник на CodePen