Понг - отличная игра, в которую можно играть, но в нее будет еще веселее, если вы сделаете ее сами! Создание понга с помощью javascript - отличный способ начать свое путешествие в мир веб-разработчиков (хотя это может еще не показаться), изучить javascript или просто весело провести время, создавая классную игру. Итак, приступим!

Вы также можете ознакомиться с этой и другими историями по адресу: https://hershalb.com/how-to-make-pong-with-javascript/

Сначала мы приступаем к созданию необходимых движущихся частей - двух ракеток по бокам экрана и мяча посередине. Создайте новый файл «pong.html» в выбранном вами каталоге и добавьте следующий код:

<!doctype html>
<html>
<body>
<div id=”paddle1" style=”position:absolute;left:0px;top:460px;width:10px;height:150px;background-color:black;”>
</div>
<div id=”ball” style=”position:absolute;left:820px;top:510px;width:25px;height:25px;background-color:red;border-radius:50%;”>
</div>
<div id=”paddle2" style=”position:absolute;right:0px;top:460px;width:10px;height:150px;background-color:black;”>
</div>
</body>

Этот код создает два блока div с идентификаторами «paddle1» и «paddle2». Мы стилизуем лепестки так, чтобы они были 150 пикселей в высоту и 10 пикселей в ширину. Вы можете изменить это по своему усмотрению. Атрибут стиля «position: absolute» на манипуляторах позволяет нам размещать их в любом месте экрана, не беспокоясь о положении других div. Затем, «left: 0px» и «right: 0px» на каждом соответствующем манипуляторе гарантирует, что лопасти находятся на самом краю экрана. Наконец, свойство «top:…» помещает верхнюю часть каждой ракетки на 460 пикселей от верха экрана.

Div шара по сути такой же, как и лопасти, за исключением того, что левое значение изменено (потому что мы хотим, чтобы мяч находился в середине экрана), и есть свойство «border-radius: 50%», которое по существу превращает div в круг.

В зависимости от размера экрана может потребоваться изменить верхнее и левое значения, но перетащите этот файл в свой любимый браузер, и он должен выглядеть так:

Далее под закрывающим тегом основного текста нам нужно добавить теги сценария для добавления javascript в файл. Поскольку код, который мы напишем, будет небольшим, я решил добавить его в тот же html-файл, но имейте в виду, что будет разумно импортировать javascript из другого файла.

...
</body>
<script type="text/javascript">
</script>

Для чего нам нужен javascript? Нам нужно добавить что-то, что будет перемещать объекты при нажатии клавиши. Итак, как мы можем это сделать? Сначала нам нужно решить, какие переменные будут изменены. Положение лопастей изменится, они будут перемещаться вверх и вниз, чем можно будет управлять с помощью свойства стиля top, о котором упоминалось ранее. Затем нужно изменить левое и верхнее положение мяча. Мы будем вести список переменных, чтобы отслеживать всю важную информацию.

var paddleHeight = 150;
var ballRadius = 25;
var halfPaddleHeight = paddleHeight / 2;
var speedOfPaddle1 = 0;
var positionOfPaddle1 = 460;
var speedOfPaddle2 = 0;
var positionOfPaddle2 = 460;
var topPositionOfBall = 510;
var leftPositionOfBall = 820;
var topSpeedOfBall = 0;
var leftSpeedOfBall = 0;
var score1;
var score2;

Переменные должны быть понятными, но каждая отслеживает соответствующие верхнее и левое значения, так что при изменении переменных меняются и значения стиля. Теперь давайте добавим код, который перемещает лопасти вверх и вниз. Способ сделать это - определить, нажал ли пользователь клавиши вверх, вниз, W или S. Мы можем сделать это в Javascript, добавив eventListener. Исходя из этого, мы изменим верхнее значение стиля ракетки с помощью функции javascript «document.getElementById».

document.addEventListener('keydown', function (e) {
     if (e.keyCode == 87 || e.which == 87) { // W key
      positionOfPaddle1 -= 10;
      document.getElementById("paddle1").style.top = 
                                          (positionOfPaddle1) + "px" 
     }
     if (e.keyCode == 83 || e.which == 83) { // S Key
      positionOfPaddle1 += 10;
      document.getElementById("paddle1").style.top = 
                                         (positionOfPaddle1) + "px";
     }
     if (e.keyCode == 38 || e.which == 38) { // up arrow
      positionOfPaddle2 -= 10;
      document.getElementById("paddle2").style.top = 
                                         (positionOfPaddle2) + "px";
     }
     if (e.keyCode == 40 || e.which == 40) { // down arrow
      positionOfPaddle2 += 10;
      document.getElementById("paddle2").style.top = 
                                         (positionOfPaddle2) + "px";
     }
}, false);

Добавление этого в теги скрипта позволит нам изменять положение левого и правого манипулятора каждый раз, когда нажимается W, S, вверх или вниз. Теперь откройте, перезагрузите файл pong.html в своем браузере и проверьте ключи, и ... весла движутся! Однако сейчас движение очень прерывистое, но нам нужно более плавное действие. Способ, которым мы можем это сделать, заключается в постоянном обновлении положения лопастей с помощью функции, которая вызывается несколько раз в секунду. Эта функция обновит позицию верхнего стиля, а только что созданный нами прослушиватель событий обновит скорость лопастей.

document.addEventListener(‘keydown’, function (e) {
 if (e.keyCode == 87 || e.which == 87) { // W key
 speedOfPaddle1 = -10;
 }
 if (e.keyCode == 83 || e.which == 83) { // S Key
 speedOfPaddle1 = 10;
 }
 if (e.keyCode == 38 || e.which == 38) { // up arrow
 speedOfPaddle2 = -10;
 }
 if (e.keyCode == 40 || e.which == 40) { // down arrow
 speedOfPaddle2 = 10;
 }
}, false);
// This function gets called 60 times per second window.setInterval(function show() {
 positionOfPaddle1 += speedOfPaddle1;
 positionOfPaddle2 += speedOfPaddle2;
document.getElementById(“paddle1”).style.top = 
                               (positionOfPaddle1) + “px”;
 document.getElementById(“paddle2”).style.top = 
                               (positionOfPaddle2) + “px”;
}, 1000/60);

Теперь, перезагружая документ, мы видим, что нажатие клавиш со стрелками вверх и вниз перемещает ракетку гораздо более плавно, но при этом она не останавливается! Как мы можем остановить лопасти, как только мы отпускаем клавишу, которую нажимаем? Все, что нам нужно сделать, это добавить еще один прослушиватель событий для действия «keyup». То же, что и в прошлый раз, но для любого действия по нажатию будет установлено значение 0. Попробуйте сначала написать это сами, а затем взгляните на приведенный ниже код.

document.addEventListener(‘keyup’, function (e) {
 if (e.keyCode == 87 || e.which == 87) {
 speedOfPaddle1 = 0;
 }
 if (e.keyCode == 83 || e.which == 83) {
 speedOfPaddle1 = 0;
 }
 if (e.keyCode == 38 || e.which == 38) {
 speedOfPaddle2 = 0;
 }
 if (e.keyCode == 40 || e.which == 40) {
 speedOfPaddle2 = 0;
 }
}, false);

Действие клавиатуры запускается, когда клавиша со стрелкой отпускается, а действие нажатия клавиши запускается, когда клавиша нажата. Поэтому, когда вы перестанете нажимать кнопку, лопатка перестанет двигаться. Перезагрузите документ, и теперь у нас есть плавное движение весла, которое останавливается, как только вы отпускаете клавишу. Теперь все, что нам нужно сделать, это добавить операторы if в функцию window.setInterval, чтобы гарантировать, что лопасти останавливаются в определенной точке (если вы продолжаете удерживать стрелку вниз, лопатка будет непрерывно перемещаться вниз).

positionOfPaddle1 += speedOfPaddle1;
positionOfPaddle2 += speedOfPaddle2;
if (positionOfPaddle1 <= 150) {
 positionOfPaddle1 = 150;
}
if (positionOfPaddle2 <= 150) {
 positionOfPaddle2 = 150;
}
if (positionOfPaddle1 >= window.innerHeight — paddleHeight) {
 positionOfPaddle1 = window.innerHeight — paddleHeight;
}
if (positionOfPaddle2 > window.innerHeight — paddleHeight) {
 positionOfPaddle2 = window.innerHeight — paddleHeight;
}
...

Эта функция говорит, что если положение ракетки равно 150 (это число было выбрано, чтобы оставить место для названия и оценок) от верхней части экрана, не меняйте положение ракетки. Если весло находится на расстоянии длины весла от нижней части экрана, остановите весло. Попробовав игру еще раз, мы увидим, что весла не выходят за пределы определенной точки. Теперь мы должны обработать движение мяча.

Мы сразу знаем, что положение мяча должно обновляться в зависимости от скорости мяча, поэтому добавьте правильный код в функцию setInterval.

topPositionOfBall += topSpeedOfBall;
leftPositionOfBall += leftSpeedOfBall;
...
document.getElementById("ball").style.top = 
                                  (topPositionOfBall) + "px";
 document.getElementById("ball").style.left = 
                                  (leftPositionOfBall) + "px";

На скорость мяча не влияет какое-либо нажатие клавиш, поэтому мы должны создать функцию, которая дает установленную скорость мячу, как только документ загружается. Это можно сделать в первом теге тела. А в тегах скрипта мы добавим функцию startBall (), которая дает мячу случайную левую и максимальную скорость.

<html>
<body onload="startBall()"
...
...
<script>
function startBall() {
topPositionOfBall = 510;
leftPositionOfBall = 820;
if (Math.random() < 0.5) {
  var side = 1
 } else {
  var side = -1
 }
 topSpeedOfBall = Math.random() * -2 - 3;
 leftSpeedOfBall = side * (Math.random() * 2 + 3);
};
</script>

Функция start ball создает новую сторону переменной на основе Math.random. Math.random () возвращает случайное число от 0 до 1. Если сторона отрицательная, мяч переместится влево. Если сторона положительная, мяч переместится вправо. Далее скорость мяча задается случайными значениями. (Math.random () * 2 + 3) может показаться произвольным, но это значения, с которыми вы можете поиграть, чтобы увидеть, с какой скоростью вы хотите, чтобы мяч двигался. Причина, по которой мы устанавливаем leftPos и ​​topPos для мяча, состоит в том, чтобы гарантировать, что когда мы начинаем новую игру, мяч сначала центрируется.

Наконец, нам нужно снова добавить операторы if, чтобы остановить мяч в определенных точках, но вместо того, чтобы заставить мяч перестать двигаться, мы хотим, чтобы мяч отражался от поверхности. Если он отскакивает от верхней части экрана, максимальная скорость станет отрицательной, и он пойдет в другом направлении. Та же идея применима к нижней части экрана. Мы добавим этот код в функцию setInterval под другими операторами if.

if (topPositionOfBall <= 150 || 
    topPositionOfBall >= window.innerHeight — ballRadius) {
 topSpeedOfBall = -topSpeedOfBall
 }

Теперь мы должны добавить один и тот же код в левую и правую часть экрана, но только если ракетка находится рядом с ней. В противном случае мы хотим начать новый раунд, вызвав startBall (). Для этого нам нужно добавить дополнительные операторы if в функцию setInterval и проверить положение мяча в соответствии с положением ракеток.

if (leftPositionOfBall <= paddleWidth) {
 if (topPositionOfBall > positionOfPaddle1 && 
          topPositionOfBall < positionOfPaddle1 + paddleHeight) {
     leftSpeedOfBall = -leftSpeedOfBall;
 } else {
     startBall();
 }
}
if (leftPositionOfBall >= window.innerWidth — ballRadius - paddleWidth) {
 if (topPositionOfBall > positionOfPaddle2 && 
          topPositionOfBall < positionOfPaddle2 + paddleHeight) {
     leftSpeedOfBall = -leftSpeedOfBall
 } else {
     startBall();
 }
}

Если положение мяча слева от первой ракетки, и мяч находится между двумя концами ракетки, скорость мяча уменьшается. То же самое и с правой стороны. Теперь у нас есть полностью функционирующая игра Pong, единственное, что нам сейчас нужно, это название и очки, чтобы игра выглядела лучше. Для этого нужно добавить заголовки для оценок и заголовок в html.

<body onload=”startBall()”>
<h1 style=”position:absolute;left:45%;top:10px;font-size:70px;”>Pong</h1>
<h1 style=”position:absolute;left:30px;top:80px;”>Score 1: <span id=”score1">0</span></h1>
<h1 style=”position:absolute;right:30px;top:80px;”>Score 2: <span id=”score2">0</span></h1>
<hr style=”margin-top:150px;”>

Теперь экран должен выглядеть так:

Теперь нам нужно отредактировать партитуры. Когда мы вызываем startBall (), мы знаем, что счет изменится, поэтому, если мы вызываем startBall () после того, как мяч прошел мимо левой ракетки, оценка2 увеличится на 1, и то же самое относится к стороне езды. Используя тот же код, что и выше:

if (leftPositionOfBall <= paddleWidth) {
 if (topPositionOfBall > positionOfPaddle1 && 
          topPositionOfBall < positionOfPaddle1 + paddleHeight) {
     leftSpeedOfBall = -leftSpeedOfBall;
 } else {
     score2++;
     startBall();
 }
}
if (leftPositionOfBall >= window.innerWidth — ballRadius - paddleWidth) {
 if (topPositionOfBall > positionOfPaddle2 && 
          topPositionOfBall < positionOfPaddle2 + paddleHeight) {
     leftSpeedOfBall = -leftSpeedOfBall
 } else {
     score1++;
     startBall();
 }
}
...
document.getElementById('score1').innerHTML = score1.toString();
document.getElementById('score2').innerHTML = score2.toString();

Теперь перезагрузите страницу, и у вас есть полностью работающая игра в Понг! Теперь, когда вы сделали это сами, стало еще веселее! Ознакомьтесь с полным исходным кодом здесь. Затем вы можете попробовать внести в игру свои собственные забавные изменения: включить звуки, когда мяч ударяется о ракетку, сделать мяч изображением, создать фоновое изображение или добавить кнопки в игру. Наслаждаться!