Добрый день, уважаемые читатели!
Сегодня мы продолжаем писать нашу игру на canvas. И теперь мы переходим к самому интересному — атаке.
В данной статье мы сделаем:
- Анимацию игрока во время атаки
- Добавим возможность атаковать
- Добавим сам снаряд, которым атакует игрок
- Местами поправим наш код
Поехали!
Анимация игрока во время атаки
Прежде всего я обновил файл с анимациями игрока и добавил новые кадры атаки, а заодно и стрелу, которой будет атаковать наш игрок:
Теперь пропишем анимацию атаки в коде.
animationsPlayer = { ... attackRight: [ 371, 20, 50, 51, 435, 20, 50, 51, 547, 20, 50, 51 ], attackLeft: [ 378, 79, 50, 51, 435, 79, 50, 51, 488, 79, 50, 51 ] };
Готово.
Внесем сразу несколько переменных, которые нам понадобятся для стрельбы:
var canvasWidth = 600,//window.innerWidth; canvasHeight = 500,//window.innerHeight; direction = 'right', // изменили начальное значение arrowDirection = '', arrowSpeed = 6, wizardSpeed = 0.5, wizards = [], lights = [], // массив объектов молний arrows = [], health = 100, lastFire = Date.now(); // для расчета стрельбы
Переменная lastFire понадобится для того, чтобы ограничить стрельбу игрока по времени.
Добавим игроку стрел:
player.speed = 3; player.sizeX = 50; player.sizeY = 50; player.arrows = 100;
Выведем на экран количество стрел:
var gameLoop = new Konva.Animation(function(frame) { ... simpleText.setAttr('text', 'Молний: ' + lights.length + ", Магов на карте: " + wizards.length + ' Здоровье: ' + Math.floor(health) + ", Стрел: " + player.arrows); ... }, layer);
Добавим возможность атаковать
Добавим возможность стрельбы по нажатию пробела. Здесь ничего сложного, если у игрока есть стрелы и с последнего выстрела прошло больше 500 мсек, то производим выстрел.
Для определения куда, полетит стрела мы добавим условие на проверку direction.
function handleInput() { if (player.attrs.animation == 'attackRight' || player.attrs.animation == 'attackLeft') { animationAttack(); return; } ... if (direction == 'left') { player.attrs.animation = 'idleLeft'; } if(input.isDown('DOWN') || input.isDown('s')) { if (player.attrs.y + player.speed < canvasHeight - player.sizeY) { ... direction = 'right'; } } if(input.isDown('UP') || input.isDown('w')) { if (player.attrs.y - player.speed > 0) { ... direction = 'left'; } } ... if(input.isDown('SPACE') && Date.now() - lastFire > 500 && player.arrows > 0) { player.attrs.animation = 'attackLeft'; if (direction == 'right') { player.attrs.animation = 'attackRight'; } player.frameIndex(0); } }
В самом начале фунции мы проверяем, если игрок уже атакует, то мы запрещаем ему двигаться и выходим из функции по return. Сейчас займемся написанием функции animationAttack.
function animationAttack() { if (player.frameIndex() >= 2) { makeBullet('arrow'); } }
Здесь по наступлению 3 фрейма анимации мы создаем стрелу.
Код для создания стрелы ниже:
function makeBullet(type, x, y) { if (type == 'light') { ... // add the shape to the layer layer.add(light); // add the layer to the stage stage.add(layer); // start sprite animation light.start(); } if (type == 'arrow') { var x = player.attrs.x; var y = player.attrs.y; var arrow = new Konva.Image({ x: player.attrs.x + 25, y: player.attrs.y + 20, image: playerImg, width: 30, height: 10 }); // вырезаем стрелу из изображения игрока arrow.crop({ x: 7, y: 150, width: 30, height: 10 }); arrow.direction = 'left'; player.attrs.animation = 'idleLeft'; if (direction == 'right') { arrow.direction = 'right'; player.attrs.animation = 'idleRight'; arrow.crop({ x: 7, y: 137, width: 30, height: 10 }); } player.arrows--; player.frameIndex(0); arrows.push(arrow); // add the shape to the layer layer.add(arrow); // add the layer to the stage stage.add(layer); lastFire = Date.now(); } }
В начале мы внесли код добавления молнии в условие if (type == ‘light’). Далее дописали добавление стрелы. Механизм такой же, как и для молнии. Только, чтобы получить статическое изображение стрелы, мы обрезали изображение игрока и оставили только область со стрелой. Причем в зависимости от направления стрелы меняется область для вырезания.
По направлению игрока мы определяем направление полета стрелы. Далее уменьшаем количество стрел у игрока и добавляем стрелы в массив стрел.
И самое важное, чтобы игрок не стрелял, как из пулемета мы обновляем переменную lastFire, которую объявляли ранее. Вот тут она и пригодилась.
Летящая стрела
Когда мы создали стрелу, ее необходимо анимировать.
function moveBullet() { ... // Update all the arrows for(var i = 0; i < arrows.length; i++) { var arrow = arrows[i]; switch(arrow.direction) { case 'right': arrow.setX(arrow.attrs.x + arrowSpeed); break; default: arrow.setX(arrow.attrs.x - arrowSpeed); } // удаляем стрелы за экраном if (arrow.attrs.x < 0 || arrow.attrs.x > canvasWidth) { arrows.splice(i, 1); arrow.setX(-1000); i--; } } }
Тут по сути ничего сложного. Каждый игровой цикл вызывается функция moveBullet, которая перебирает все стрелы и обновляет их координаты в зависимости от направления полета стрелы.
Если стрелы вышла за пределы экрана, то мы ее удаляем из массива стрел и забываем про нее.
Вот, что у нас получилось в итоге:
Как вы заметили выше, я убрал зеленый фон у молний 🙂 Так гораздо лучше 🙂
На сегодня на этом остановимся. И в следующий раз мы займемся попаданием стрел во врага.
Подписывайтесь на рассылку 😉 Дальше интересней!
Если вопросы/пожелания? Пишите в комментарии.
Всем спасибо за внимание.