Попробуйте продержаться как можно дольше.
Завершаем трилогию про пинг-понг на JavaScript. Если в прошлой частимы сделали не слишком умного бота, то теперь всё серьёзно — победить этого противника физически невозможно. Платформа всегда отобьёт мяч, а ваша новая задача — постичь дзен и поставить новый рекорд.
Подготовка
За основу возьмём наш последний код из второй части, когда платформа движется сама.
Что будем делать сегодня:
- Настроим всё, чтобы левая платформа всегда следовала за мячом.
- Добавим подсчёт очков.
- Сделаем так, чтобы компьютер запоминал новый рекорд и выводил его при каждой игре.
- Наконец-то уберём код, который отвечает за управление левой платформой с клавиатуры.
Настраиваем левую платформу Сначала нам нужно отключить автостарт платформы при запуске игры. Находим строчку 53 и удаляем такое:
leftPaddle.dy = paddleSpeed;
Теперь платформа не будет никуда рандомно двигаться. Дальше отключаем автоматический отскок от границ поля — удаляем ненужные строки, которые добавляли для этого:
А теперь делаем магию — добавляем автоматическое слежение платформы за мячом. Для этого находим фрагмент, который отвечает за движение мяча, и добавляем после него такое:
// Если мяч на предыдущем шаге куда-то двигался — пусть продолжает двигаться
ball.x += ball.dx; ball.y += ball.dy;
// пусть платформа движется так же, как и мяч
leftPaddle.dy = ball.dy;
Смысл тут вот в чём: нас интересует только движение мячика вверх или вниз, а за это отвечает свойство .dy. Мы берём его из мячика и отдаём в платформу. Теперь она будет двигаться вниз, если мяч идёт вниз, и вверх — если мяч летит вверх.
Считаем очки
Принцип будет такой:
- Сначала у игрока 0 очков. Рекорд — тоже 0.
- За каждое отбивание мяча игрок получает одно очко.
- Если игрок побил свой старый рекорд — он тут же обновляется на текущее значение очков.
- Когда мяч улетел за платформу, очки обнуляются, а рекорд остаётся.
- Постоянно выводим на экран оба этих показателя: рекорд и количество набранных очков.
Делаем нужные переменные. Находим в самом начале раздел с переменными и добавляем нужный код после скорости мяча:
// Рекорд var record = 0; // Набранные очки var count = 0;
Добавляем очки за отбивания игроком. Теперь нам нужно найти код, который проверяет касание правой платформы, и если было касание — увеличить количество набранных очков на единицу (count += 1;):
// Проверяем и делаем то же самое для правой платформы
else if (collides(ball, rightPaddle)) { ball.dx *= -1;
ball.x = rightPaddle.x - ball.width; count +=1; }
Следим за рекордом. Здесь всё просто: как только игрок пропустил мяч, мы смотрим, сколько очков он набрал к этому моменту. Если их больше, чем текущее значение больше рекорда, — записываем их как новый рекорд и обнуляем.
Всё это мы сделаем в коде, который обрабатывает вылет мяча за край платформы:
// Если мяч улетел за игровое поле влево или вправо — перезапускаем его if ( (ball.x < 0 || ball.x > canvas.width) && !ball.resetting) {
// Помечаем, что мяч перезапущен, чтобы не зациклиться
ball.resetting = true;
// Если игрок набрал больше рекорда — записываем это как новый рекорд
if (count > record) { record = count };
// Обнуляем количество очков у игрока count = 0;
// ДАЛЬШЕ ИДЁТ ОСТАЛЬНОЙ КОД ОБРАБОТКИ ВЫЛЕТА, ЕГО НЕ ТРОГАЕМ
Сохраняем рекорд в памяти компьютера. Когда мы делали свой планировщик задач на JavaScript, мы использовали localStorage для хранения данных в памяти браузера. Используем этот же подход, чтобы таким же образом сохранить текущее значение рекорда игрока.
Смысл в том, что мы точно так же, как и в планировщике, проверяем сначала размер хранилища. Если оно не пустое и в нём что-то есть — достаём значение рекорда оттуда. Если пустое — заводим запись и кладём туда ноль (значит, что рекорд пока никто не поставил). Добавим этот код после блока с переменными:
// Узнаём размер хранилища var Storage_size = localStorage.length;
// Если в хранилище что-то есть… if (Storage_size > 0){
// Достаём оттуда текущее значение рекорда
record = localStorage.getItem('record');
// Если там ничего нет — } else {
// Делаем новую запись и кладём туда ноль — рекорда пока нет localStorage.setItem('record',0); }
У нас есть место, где мы можем его хранить. Осталось только сохранить значение рекорда в памяти браузера. Для этого добавим такой код в блок обработки вылета мяча за игровое поле, сразу после обнуления значения набранных очков пользователя:
// Кладём значение рекорда в хранилище браузера localStorage.setItem('record',record);
Добавляем вывод значений на экран. Будем использовать стандартные свойства объекта context:
- fillStyle — отвечает за цвет надписей (и за цвет в принципе),
- font — каким шрифтом будем выводить надписи,
- fillText — выводит заданный текст в определённых координатах.
Давайте слева выведем текущее значение рекорда, а справа — количество очков, набранных за игру. Этот код нужно вставить в самый конец главного цикла, сразу после блока обработки нажатия клавиш:
// Цвет текста context.fillStyle = "# ff0000";
// Задаём размер и шрифт context.font = "20pt Courier";
// Сначала выводим рекорд context.fillText('Рекорд: ' + record, 150, 550);
// Затем — набранные очки context.fillText(count, 450, 550);
Убираем обработку нажатий
Единственное, что мы ещё не сделали — не убрали реакцию на клавиши управления левой платформой. Исправим это — найдём и удалим вот этот код:
// Если нажата клавиша W, if (e.which === 87) {
// то двигаем левую платформу вверх
leftPaddle.dy = -paddleSpeed; }
// Если нажата клавиша S,
else if (e.which === 83) {
// то двигаем левую платформу вниз
leftPaddle.dy = paddleSpeed; }
И этот:
// А если это W или S,
if (e.which === 83 || e.which === 87) {
// останавливаем левую платформу leftPaddle.dy = 0; }
Готовый код
Больше статей о программирование, IT и технологиях на нашем сайте: https://thecode.media/