Перейти к основному содержимому

Инструкции по выполнению шага

Теперь, когда основные механики игры уже реализованы, можно заняться внедрением дополнительных функций. Одна из самых распространённых функций в играх это возможность поставить игровой процесс на паузу.

Для начала создадим новый скрипт и назовём его pause.js. Привяжем этот скрипт в index.html перед подключением скрипта с управлением controls.js:

<!-- Начало места, которое мы изменяем -->
<img src="assets/background.jpg" id="background"></img>
<script src="js/render.js"></script>
<script src="js/pause.js"></script>
<script src="js/controls.js"></script>
<script src="js/engine.js"></script>
</body>

</html>
<!-- Конец редактирования -->

Вот так будет выглядеть наша папка проекта после создания файла pause.js:

ping-pong
├── index.html
├── assets
│ ├── ball.png
│ ├── paddle.png
│ ├── background.jpg
│ └── style.css
└── js
├── render.js
├── engine.js
├── controls.js
└── pause.js

Добавим в только что созданный файл следующий код:

var isPaused = false;
// https://stackoverflow.com/questions/16554094/canvas-requestanimationframe-pause
window.requestAnimFrame = (function () {
return (
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function (callback) {
window.setTimeout(callback, 1000 / 60);
}
);
})();

// Отслеживаем нажатия клавишы
document.addEventListener("keydown", function (e) {
// Если нажата клавиша ESC,
if (e.which !== 27) return;
console.log('Paused');
isPaused = !isPaused;
// Рисуем иконку паузы
pauseDisplay();
});

Мы создали переменную-переключатель isPaused, которая хранит состояние игры. Это булева переменная и она может принимать два значения: false или true. Аналогично как мы это делали в шаге 5, добавим обработчик событий нажатий на клавишу Escape. При этом переводим наш переключатель в другое состояние. Если в переменной isPaused было записано значение false, то после нажатия на клавишу паузы значение будет уже true.

В обработчике событий вызывается функция pauseDisplay(). Это нестандартная функция JavaScript. Из названия можно догадаться, что она отвечает за отрисовку состояния игры во время паузы. Т.к. вся отрисовка лежит в скрипте render.js, нужно добавить туда следующее:

к сведению

Следующую часть кода добавляем в конец файла render.js.

// Функция отрисовки иконки паузы
const pauseDisplay = () => {
context.fillStyle = "rgba(255, 255, 255, 0.5)";
context.fillRect(
canvas.width / 2 - canvas.width / 7,
canvas.height / 3,
canvas.width / 10,
canvas.height / 3
);
context.fillRect(
canvas.width / 2 + canvas.width / 24,
canvas.height / 3,
canvas.width / 10,
canvas.height / 3
);
}

Со всеми этими функциями вы уже знакомы. В fillStyle можно передать конкретное значение в палитре RGBA (Red, Green, Blue, Alpha), где альфа это число от 0 до 1. Этот параметр задаёт прозрачность цвета. Если альфа 0, то цвет полностью прозрачный, 1 – полностью непрозрачный. Говоря по существу, данная функция рисует два белых полупрозрачных прямоугольника поверх игрового экрана на нашем двухмерном холсте.

Вспомним, что redraw() у нас вызывается функцией loop() из файла engine.js. Поэтому уберите лишний вызов этой функции из файла файл render.js.

Поскольку теперь игровой процесс должен "замирать" при нажатии на кнопку паузы, то нужно контролировать вызов функции игрового движка loop() Сперва удалим из скрипта engine.js строчку (в двух местах):

requestAnimationFrame(loop);

Вместо них напишем следующее:

к сведению

Следующую часть кода добавляем в конец файла engine.js.

function Start() {
if (!isPaused) {
loop();
}
// Рекурсивный вызов игрового движка
requestAnimFrame(Start);
}

Start();
loop();

Теперь переменная isPaused контролирует вызов расчёта игрового движка.

к сведению

Итоговый результат выполнения шага можно скачать тут.