Добрый день, уважаемые читатели!
Сегодня я продолжаю писать свою небольшую игру на canvas.
Первая статья находится тут: ссылка.
Вторая тут: ссылка.
Что мы рассмотрим в этой статье?
1. Создадим молнию
2. Заставим врагов создавать молнию
3. Небольшие изменения в коде/картинке
Начали!
Анимация
Сразу обновим изображение мага и поправим координаты анимации
Обновим координаты
var animationsWizard = {};
var animationsLight = {
light: [
2, 405, 40, 39,
46, 405, 40, 39,
90, 405, 40, 39,
134, 405, 40, 39,
178, 405, 40, 39,
222, 405, 40, 39,
266, 405, 40, 39,
310, 405, 40, 39,
354, 405, 40, 39,
398, 405, 40, 39,
442, 405, 40, 39,
486, 405, 40, 39,
530, 405, 40, 39
]
}
var animationsPlayer = {
walkRight: [
2, 131, 48, 49,
52, 131, 48, 49,
102, 131, 48, 49,
152, 131, 48, 49,
202, 131, 48, 49,
252, 131, 48, 49,
302, 131, 48, 49,
352, 131, 48, 49,
402, 131, 48, 49,
452, 131, 48, 49,
502, 131, 48, 49,
552, 131, 48, 49,
602, 131, 48, 49,
652, 131, 48, 49,
702, 131, 48, 49,
752, 131, 48, 49,
802, 131, 48, 49,
852, 131, 48, 49
],
walkLeft: [
2, 191, 48, 49,
52, 191, 48, 49,
102, 191, 48, 49,
152, 191, 48, 49,
202, 191, 48, 49,
252, 191, 48, 49,
302, 191, 48, 49,
352, 191, 48, 49,
402, 191, 48, 49,
452, 191, 48, 49,
502, 191, 48, 49,
552, 191, 48, 49,
602, 191, 48, 49,
652, 191, 48, 49,
702, 191, 48, 49,
752, 191, 48, 49,
802, 191, 48, 49,
852, 191, 48, 49
],
idleRight: [
...
],
idleLeft: [
...
],
attackLeft: [
25, 250, 48, 67,
123, 250, 48, 67,
221, 250, 48, 67,
319, 250, 48, 67,
417, 250, 48, 67,
515, 250, 48, 67,
613, 250, 48, 67,
711, 250, 48, 67,
809, 250, 48, 67,
907, 250, 48, 67,
1005, 250, 48, 67,
1103, 250, 48, 67
]
};
Создание молнии
Начнем с создания молнии. Прежде всего добавим массив молний, а заодно и перенесем массив магов повыше:
var direction = ''; var wizardSpeed = 0.5; var wizards = []; var lights = []; // массив объектов молний
Анимацию для молнии мы уже написали выше в списке анимаций.
Загрузим изображение молнии:
var wizardImg = new Image(); wizardImg.src = 'wizard.png'; var lightImg = new Image(); lightImg.src = 'wizard.png';
Напишем функцию создания нашей молнии. Далее будем использовать данную функцию не только для молний, но и для других атакующих вещей.
function makeBullet(type, x, y) {
if (type == 'light') {
light = new Konva.Sprite({
x: x,
y: y,
image: lightImg,
animation: 'light',
animations: animationsLight,
frameRate: 7,
frameIndex: 0
});
lights.push(light);
}
// add the shape to the layer
layer.add(light);
// add the layer to the stage
stage.add(layer);
// start sprite animation
light.start();
}
В функцию передаем тип и координаты объекта.
Создадим для теста пару молний:
makeBullet('light', 100, 100);
makeBullet('light', 400, 100);
Вот наши молнии, которые зацикленно бьют в землю:

По задумке молния должна бить 1 раз и пропадать в поля игры. Доработаем код и добавим новую функцию, которая будет пробегаться по списку молний и удалять ту, у которой анимация подошла к конечному кадру.
function moveBullet() {
// молния
var i;
for(i = 0; i < lights.length; i++) {
if (lights[i].frameIndex() > (animationsLight.light.length) / 4 - 2) {
lights[i].setX(-10000); // сдвигаем за край экрана
lights.splice(i,1); //удаляем 1 эл. с индексом i
}
}
}
Теперь наши молнии пропадают с поля. Теперь перейдем ко второй задаче. Заставим врагов создавать молнию около игрока.
function actEnemies() {
for(i = 0; i < wizards.length; i++) {
wizards[i].mana++;
if (wizards[i].mana > 400 && (wizards[i].attrs.animation == 'idleLeft' || wizards[i].attrs.animation == 'idleRight')) {
wizards[i].action = 'makeLight';
wizards[i].attrs.animation = 'attackLeft';
wizards[i].setY(wizards[i].attrs.y - 18);
wizards[i].mana -= 400;
}
// кастование молнии после 10 кадра
if (wizards[i].action == 'makeLight' && wizards[i].frameIndex() > 10) {
wizards[i].setY(wizards[i].attrs.y + 18);
makeBullet('light', Math.floor((Math.random() * 200) + player.attrs.x - 100), Math.floor((Math.random() * 200) + player.attrs.y - 100));
wizards[i].action = 'stay';
}
}
}
Каждый вызов функции у мага увеличивается количество магической энергии. Когда ее переваливает за 400, то маг атакует игрока. Действие противника меняется на makeLight и начинается процесс создания молнии. После того, как проходит 10-ый кадр анимации кастования молнии, появляется сама молния.
В строке 9 и 15 мы смещаем врага по вертикали, так как размер кадра мага, который стоит по высоте меньше, чем размер кадра мага, который создает молнию. Чтобы при смене анимации маг оставался на месте, я добавил смещение по оси Y в одну и в другую сторону.
В строке 16 мы задаем случайную координату для молнии около игрока.
Здесь так же используется свойства mana, которого пока нет у мага. Поэтому добавим его в функцию создания:
function makeEnemy(type, x, y) {
...
wizard.direction = 'right';
wizard.action = '';
wizard.mana = 0;
...
}
А теперь зациклим вызов функций:
var gameLoop = new Konva.Animation(function(frame) {
...
moveBullet();
actEnemies();
}
Осталось добавить лишь небольшое условие для магов, чтобы не было конфликта между анимацией «стоять» и «атака»:
function moveEnemies() {
wizards.forEach(function(wizard) {
if (wizard.action != 'makeLight') {
...
}
})
}
Все! Отлично! Теперь нас постоянно атакуют молниями.
И небольшая добавка. Выведем для справки на экран количество магов и количество молний.
var simpleText = new Konva.Text({
x: 15,
y: 15,
text: 'text',
fontSize: 18,
fill: 'black'
});
layer.add(simpleText);
// бесконечный цикл игры
var gameLoop = new Konva.Animation(function(frame) {
...
simpleText.setAttr('text', 'Молний: ' + lights.length + ", Магов на карте: " + wizards.length);
}
Теперь на экран видим это:

На сегодня хватит.
В следующей статье я расскажу, как организовать столкновение игрока с молнией и, соответственно, как сделать урон от этой молнии. И начнем потихоньку заниматься уже атакой со стороны игрока.
Остались вопросы? Пишите в комментарии! Есть советы/подсказки? Так же пишите! 🙂 Будем вместе улучшать игру 🙂
Спасибо за внимание! Подписывайтесь на рассылку 😉
