Заключение

Это 10-й и заключительный шаг в Gamedev Canvas tutorial. Вы можете найти исходный код, как он должен выглядеть, после завершения этого урока в Gamedev-Canvas-workshop/lesson10.html.

В любой игре, которую мы пишем, всегда есть место для улучшений. Например, мы можем предложить игроку несколько жизней. Они могут сделать несколько ошибок и все равно закончить игру. Мы также можем улучшить отрисовку кода.

Предоставление игроку нескольких жизней

Реализация довольно проста. Давайте сначала добавим переменную для хранения количества жизней в том же месте, где мы объявляли другие наши переменные:

var lives = 3;

Отрисовка счетчика жизни выглядит почти так же, как и счетчика баллов - добавьте в код следующую функцию под функцией drawScore() :

function drawLives() {
    ctx.font = "16px Arial";
    ctx.fillStyle = "#0095DD";
    ctx.fillText("Lives: "+lives, canvas.width-65, 20);
}

Вместо того, чтобы немедленно закончить игру, мы уменьшим количество жизней, пока они больше не будут доступны. Мы также можем сбросить позиции мяча и биты, когда игрок начинает игру со следующей жизнью. Итак, в функции draw() замените следующие три строки:

alert("GAME OVER");
document.location.reload();
clearInterval(interval); // Needed for Chrome to end game

Давайте добавим немного более сложную логику к ней, как показано ниже:

lives--;
if(!lives) {
    alert("GAME OVER");
    document.location.reload();
}
else {
    x = canvas.width/2;
    y = canvas.height-30;
    dx = 2;
    dy = -2;
    paddleX = (canvas.width-paddleWidth)/2;
}

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

Визуализация дисплея жизней

Теперь вам нужно добавить вызов drawLives() внутри функции draw() и добавить его под вызовом drawScore().

drawLives();

Улучшение рендеринга с requestAnimationFrame()

Теперь давайте работать над чем-то, что не связано с игровой механикой, но с тем, как она рендерится. requestAnimationFrame поможет браузеру рендерить игру лучше, чем фиксированная частота кадров, которую в настоящее время мы реализовали, используя setInterval(). Замените следующую строку:

setInterval(draw, 10);

на:

draw();

и удалите каждый экземпляр:

clearInterval(interval); // Needed for Chrome to end game

Затем в самом низу функции draw() (непосредственно перед закрывающей фигурной скобкой) добавьте следующую строку, которая заставляет функцию draw() вызывать себя снова и снова:

requestAnimationFrame(draw);

Функция draw() теперь выполняется снова и снова в цикле requestAnimationFrame(), но вместо фиксированной частоты кадров в 10 миллисекунд, мы возвращаем управление частотой кадров обратно в браузер. Соответственно он будет синхронизировать частоту кадров и отображать фигуры только при необходимости. Это обеспечивает более эффективный и плавный цикл анимации, чем более старый метод setInterval().

Сравните свой код

Вот и все-финальная версия игры готова!

Упражнение: измените количество жизней и угол отскока мяча от биты.

Игра закончена - на данный момент!

Вы закончили все уроки — поздравляем! К этому моменту вы должны знать основы манипулирования canvas и логику простых 2D-игр. Сейчас самое время изучить некоторые фреймворки и продолжить разработку игр. Вы можете проверить аналог этой серии, 2D breakout game using Phaser или Cyber Orb built in Phaser учебник. Вы также можете просмотреть раздел Games section on MDN для вдохновения и  увеличения знаний.

Вы также можете вернуться на this tutorial series' index page учебника. Получайте удовольствие от написания кода!