Добрый день, уважаемые читатели!
Сегодня я продолжаю писать свою небольшую игру на canvas.
Первая статья находится тут: ссылка.
Вторая тут: ссылка.
Третья тут: ссылка.
Что мы рассмотрим в этой статье?
1. Добавим игроку здоровье
2. Напишем функцию столкновений игрока с молниями
3. Изменим спрайт игрока, чтобы было веселей 🙂
Поехали!
Добавим здоровье
Если нашего героя можно будет атаковать, то ему должен причиняться ущерб.
Добавим переменную здоровья и заодно немного поправим наш код.
Заменим это:
var canvasWidth = 600; var canvasHeight = 500; var direction = ''; var wizardSpeed = 0.5; var wizards = []; var lights = [];
На это:
var canvasWidth = 600, canvasHeight = 500, direction = '', wizardSpeed = 0.5, wizards = [], lights = [], health = 100;
Сделаем игроку авторегенерацию здоровья:
function getHealth(count) {
health += 0.1;
if (health > 100) {
health = 100;
}
}
При каждом вызове функции будем увеличивать значение здоровья на определенное число. Потом мы допишем влияние значения count.
Регенирироваться здоровье будет каждый игровой цикл. Добавим вызов в функцию gameLoop(), а так же добавим вывод значения здоровья:
// бесконечный цикл игры
var gameLoop = new Konva.Animation(function(frame) {
...
simpleText.setAttr('text', 'Молний: ' + lights.length + ", Магов на карте: " + wizards.length + ' Здоровье: ' + Math.floor(health));
getHealth();
}, layer);
Изменим спрайт игрока
По задумке игры игрок должен быть лучником 🙂 Поэтому изменим спрайт.

Вот такой спрайт я нашел. Первые три кадра слева направо — анимация стоячего игрока. Далее 4 кадра для бега.
Внесем нужные изменения анимации в код игры.
Следующий код:
var animationsPlayer = {
walkRight: [
2, 131, 48, 49,
52, 131, 48, 49,
Поменяем на:
var animationsWizard = {
walkRight: [
2, 131, 48, 49,
52, 131, 48, 49,
Строчку ниже удалим:
animationsWizard = animationsPlayer;
И добавим после удаленной строки новую анимацию для игрока:
animationsPlayer = {
idleRight: [
0, 20, 50, 51,
53, 20, 50, 51,
107, 20, 50, 51
],
idleLeft: [
0, 79, 50, 51,
53, 79, 50, 51,
107, 79, 50, 51
],
walkLeft: [
161, 79, 50, 51,
214, 79, 50, 51,
267, 79, 50, 51,
319, 79, 50, 51
],
walkRight: [
161, 20, 50, 51,
214, 20, 50, 51,
267, 20, 50, 51,
319, 20, 50, 51
]
};
Так как изменилось имя спрайта для игрока, то поменяем это в коде:
var playerImg = new Image(); playerImg.src = 'player.png';
Так же я решил немного увеличить скорость движения игрока:
player.speed = 3;
В итоге получилось следующее:

По-моему, неплохо. Анимация работает.
С игроком все. Перейдем к разработке столкновений.
Столкновения с молнией
Я не стал изобретать велосипед и взял готовую функцию для столкновений двух 2D прямоугольников.
Фактически, если один прямоугольник задевает второй любым краем/стороной, то у нас возникает столкновение.
function collides(x, y, r, b, x2, y2, r2, b2) {
return !(r <= x2 || x > r2 ||
b <= y2 || y > b2);
}
function boxCollides(pos, size, pos2, size2) {
return collides(pos[0], pos[1],
pos[0] + size[0], pos[1] + size[1],
pos2[0], pos2[1],
pos2[0] + size2[0], pos2[1] + size2[1]);
}
function checkCollisions() {
var i;
var pos = [];
pos[0] = player.attrs.x;
pos[1] = player.attrs.y;
// Run collision detection for all enemies and bullets
for(i = 0; i < lights.length; i++) {
var size = [],
enemyPos = [],
enemySize = [];
size[0] = 50;
size[1] = 50;
enemyPos[0] = lights[i].attrs.x;
enemyPos[1] = lights[i].attrs.y;
enemySize[0] = 50;
enemySize[1] = 50;
// в параметрах размеры и позиция игрока и объекта
if (boxCollides(enemyPos, enemySize, pos, size)) {
health--;
}
}
}
Мы в функции checkCollisions в цикле перебираем все молнии и проверяем, пересекает ли образный прямоугольник молнии прямоугольник игрока. Если да, то уменьшаем у игрока здоровье.
Все готово 🙂
На этом на сегодня все. Далее уже будем заниматься атакой со стороны игрока. Будем учить нашего героя пускать стрелы в врагов.
Остались вопросы? Пишите в комментариях.
Спасибо за внимание!
Подписывайтесь на рассылку 😉