Инструкции по выполнению шага
Теперь, когда основные механики игры уже реализованы, можно заняться внедрением дополнительных функций. Одна из самых распространённых функций в играх это возможность поставить игровой процесс на паузу.
Для начала создадим новый скрипт и назовём его 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
контролирует вызов расчёта игрового движка.
Итоговый результат выполнения шага можно скачать тут.