Инструкции по выполнению шага
Пока что результат выглядит лишь отдалённо напоминающий игру. На этом шаге с помощью скриптом сделаем отрисовку игрового поля на нашем двухмерном холсте <canvas>
. Для этого потребуется воспользоваться специальным скриптом, который будет получать доступ к элементам HTML страницы, считывать их и отображать в правильном порядке и масштабе.
Сделать это поможет язык JavaScript. Создадим в папке нашего проекта папку js
, в которую будем складывать все скрипты. После чего добавим новый пустой файл render.js
, который будет отвечать за отрисовку игрового поля.
Вот так будет выглядеть наша папка проекта после создания файла render.js
:
ping-pong
├── index.html
├── assets
│ ├── ball.png
│ ├── paddle.png
│ ├── background.jpg
│ └── style.css
└── js
└── render.js
Файл render.js
необходимо добавить в качестве внешнего файла в index.html
после элементов изображений с помощью элемента <script>
:
<!-- Начало места, которое мы изменяем -->
<img src="assets/background.jpg" id="background"></img>
<script src="js/render.js"></script>
</body>
</html>
<!-- Конец редактирования -->
Прежде всего, необходимо получить доступ к элементам HTML страницы (холсту и изображениям). Сделать это можно по уникальному идентификатору, который мы заблаговременно указали на подготовительном Шаге 0. Так, получить доступ к элементу холста можно при помощи вызова команды document.getElementById("game")
. Получим все необходимые элементы (файл render.js
):
// Обращаемся к игровому полю из документа
const canvas = document.getElementById("game");
// Обращаемся к изображению ракетки из документа
const paddleImg = document.getElementById("paddle");
// Обращаемся к изображению мячика из документа
const ballImg = document.getElementById("ball");
// Обращаемся к изображению фона из документа
const backgroundImg = document.getElementById("background");
// Размер игровой клетки
const grid = 15;
// Высота платформы
const paddleHeight = grid * 5; // 80
// Задаём максимальное расстояние, на которое могут двигаться платформы
const LeftmaxPaddleY = canvas.height - grid - paddleHeight * 2;
const RightmaxPaddleY = canvas.height - grid - paddleHeight;
// Описываем левую платформу
const leftPaddle = {
// Ставим её по центру
x: grid * 2,
y: 0,
// Ширина — одна клетка
width: grid,
// Высоту берём из константы
height: canvas.height, //paddleHeight * 2,
// Платформа на старте никуда не движется
dy: 0,
paddleSpeed: 10
};
leftPaddle.dy = 0; //paddleSpeed;
// Описываем правую платформу
const rightPaddle = {
// Ставим по центру с правой стороны
x: canvas.width - grid * 3,
y: canvas.height / 2 - paddleHeight / 2,
// Задаём такую же ширину и высоту
width: grid,
height: paddleHeight,
// Правая платформа тоже пока никуда не двигается
dy: 0,
paddleSpeed: 10
};
var ballSpeed = 5;
// Описываем мячик
const ball = {
// Он появляется в самом центре поля
x: canvas.width / 2,
y: canvas.height / 2,
// квадратный, размером с клетку
width: grid * 2,
height: grid * 2,
// На старте мяч пока не забит, поэтому убираем признак того, что мяч нужно ввести в игру заново
resetting: false,
// Подаём мяч в правый верхний угол
dx: ballSpeed,
dy: -ballSpeed
};
Фигурными скобками мы демонстрируем, что создаём словарь – набор именованных полей объекта. Это достаточно удобный способ хранения сведений о свойствах того или иного объекта. Не нужно создавать множество переменных, а достаточно одной глобальной с вложенными полями-свойствами. В дальнейшем получать значения вложенных свойств можно либо через точку (ball.x
), либо через квадратные скобки (ball["x"]
).
Данная конфигурация мячика и ракеток позволит в ближайшее время максимально удобным способом отображать объекты в нужных точках игрового поля. Но перед этим предлагается отключить видимость элементов картинок, поскольку их содержимое и так будет отображаться на холсте. Это можно сделать с помощью последовательного обращения к свойствам style
, а затем display
и присваивания ему значения "none"
:
Следующую часть кода добавляем в конец файла render.js
.
// Отключаем видимость элементов
paddleImg.style.display = "none";
ballImg.style.display = "none";
backgroundImg.style.display = "none";
Теперь при открытии страницы с игрой можно убедиться, что картинки пропали.
Наконец, необходимо расположить элементы на игровом поле. Чтобы это сделать требуется получить доступ к двухмерному представлению холста. Делается это при помощи команды getContext("2d")
:
Следующую часть кода добавляем в конец файла render.js
.
// Делаем поле двухмерным
const context = canvas.getContext("2d");
После чего производим следующие действия с двухмерным представлением холста:
Следующую часть кода добавляем в конец файла render.js
.
// Рисуем содержимое заднего фона на холст
context.drawImage(backgroundImg, 0, 0, backgroundImg.width, backgroundImg.height, 0, 0, canvas.width, canvas.height);
// Рисуем левую ракетку на холсте
context.drawImage(paddleImg, 0, 0, paddleImg.width, paddleImg.height, leftPaddle.x, leftPaddle.y, leftPaddle.width, leftPaddle.height);
// Рисуем мячик
context.drawImage(ballImg, 0, 0, ballImg.width, ballImg.height, ball.x, ball.y, ball.width, ball.height);
// Рисуем правую ракетку на холсте
context.drawImage(paddleImg, 0, 0, paddleImg.width, paddleImg.height, rightPaddle.x, rightPaddle.y, rightPaddle.width, rightPaddle.height);
// Рисуем стены
context.fillStyle = "lightgrey";
context.fillRect(0, 0, canvas.width, grid);
context.fillRect(0, canvas.height - grid, canvas.width, canvas.height);
// Рисуем сетку посередине
for (let i = grid; i < canvas.height - grid; i += grid * 2) {
context.fillRect(canvas.width / 2 - grid / 2, i, grid / 2, grid / 2);
}
Метод clearRect(x, y, width, height)
очищает пространство холста в заданной прямоугольной области, делая его прозрачным. Стоит отметить, что координаты холста вдоль горизонтальной оси х растут слева направо, а вот вдоль вертикальной оси сверху вниз. Другими словами точке с координатами (0,0)
соответствует верхний левый угол холста.
Метод drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)
позволяет перемещать фрагмент элемента <img>
в заданное место холста:
Метод fillStyle
позволяет выбрать цвет для заливки геометрических фигур, а метод fillRect(x, y, width, height)
рисует прямоугольники с заданными координатами на холсте.
Итоговый результат выполнения шага можно скачать тут.