Как устроены активные умения в игре на JS
2026-02-26 18:42 Diff

1 часть

2 часть

3 часть

В прошлый раз я описал как устроены классы персонажей, в этот раз расскажу об активных умениях.

В этот раз конструктор получился небольшим и относительно понятным.

name - название умения (только на английском. Об этом дальше).

type - тип урона (пока реализовано два: physical и piercing).

damage - указываем количество урона, которое будет нанесено врагу.

description - описание умения, которое будет появляться при наведении.

iconPath - путь до иконки умения.

animationAttackNumber - т.к. у каждого персонажа не меньше двух разных анимаций атак (их названия Attack1.png, Attack2.png...), то здесь указывается номер нужного изображения.

Вот как выглядит обычная атака у героя:

Тут нужно пояснить момент с damageInHTML. Эту функцию я прописывал отдельно, и нужно она для того чтобы в описании цифры урона подсвечивались определённым цветом, в зависимости от типа урона.

В свою очередь, в css есть соответствующие классы.

Вот теперь можно переходить к методам.

dealDamage - Тут всё просто. В зависимости от типа мы высчитываем урон. Потом этот урон вычитаем у жизней противника, и получившееся число записываем в хитбар оппонента и всплывающую табличку.

addSkillToInteface это самое страшное, что вы сегодня увидите. Этот метод делает сразу две вещи - добавляет иконку умения в HTML код, и вешает на неё onclick.

idIcon и idDescription создают id для элементов из имени умения, и именно по этой причине название умения должно быть на английском. Далее эти элементы добавляются в DOM. Включаем элемент description при наведении мыши, а на onmouseout отключаем.

В icon.onclick мы прописываем логику при нажатии мыши. Тут я использовал кучу setTimeout, чтобы анимации, такие как бег, атака и бег обратно, шли друг за другом. При вызове некоторых методов терялся контекст, так что через bind я привязал контекст где только можно было, просто на всякий случай. Логику с таймаутами я писал до того как прошёл курс по асинхронному программированию, но т.к. это была самая тяжёлая для моего понимания тема, я не уверен что с помощью async/await можно будет решить эту проблему. В ближайшей время собираюсь попробовать переписать эту логику.

Что касается класса SkillEnemy, то как и в случае с классами персонажей, он не сильно отличается от SkillHero. Главное отличие заключается в том, что в методе addSkillToInteface, мы не прописываем логику при нажатии кнопки, т.к. враг автоматически совершает атаку сразу после нашей. Вместо этого мы создаём метод useSkill, в котором и описывается логика.

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

Код проекта на GitHub.

А здесь можно поиграть в текущую версию.