Элемент «холст» HTML - один из новых элементов, добавленных в HTML5. Это контейнер фиксированного размера, который позволяет рисовать в нем графику с помощью JavaScript. Canvas имеет несколько методов для рисования контуров, прямоугольников, кругов, текста и добавления изображений. Также можно создавать интерактивные анимации и игры.

Элемент ‹canvas› - это область рисования, определенная в HTML-коде со следующими атрибутами высоты и ширины:

<canvas id=”firstCanvas” width=”500" height=”500"></canvas>

'id' здесь важен, поскольку он используется для таргетинга на этот элемент в JavaScript с помощью объектной модели документа (DOM) следующим образом:

var canvas = document.getElementById(“firstCanvas”);

В JavaScript методы рисования вызываются не в элементе холста, а в контексте рисования, который получается путем вызова .getContext (‘2d’) следующим образом:

var context = canvas.getContext(“2d”);

Этот метод определяет контекст целевого элемента холста, что означает, что у человека будет доступ к API рисования холста, который предоставляет методы и свойства для рисования на холсте. Например, если мы хотим нарисовать прямоугольник на холсте, мы можем использовать метод context.rect () следующим образом:

context.rect(20, 20, 100, 100);

Этот метод принимает четыре аргумента: координаты x и y левого верхнего угла прямоугольника, а также ширину и высоту прямоугольника: rect (x, y, width, height) . Чтобы отобразить фигуру на холсте, необходимо вызвать метод context.stroke (). Это будет выглядеть так:

Точно так же заполненный прямоугольник можно нарисовать с помощью метода .fillRect (), который принимает те же аргументы. Цвет заливки можно определить с помощью метода context.fillStyle перед вызовом метода .fillRect:

context.fillStyle= "#6c2c3a";
context.fillRect(20, 20, 100, 100);

На следующем изображении показан прямоугольник, созданный приведенными выше строками кода:

Чтобы нарисовать круг, можно использовать метод context.arc (), который принимает координаты центра, радиус круга, а также начальный и конечный угол в радианах. , что в случае круга будет от 0 до 2 * Math.PI (360 ° в радианах). Другие формы, например треугольники, также можно нарисовать, нарисовав линию для каждой стороны с помощью метода lineTo (). Помимо фигур, мы также можем рисовать текст, вставлять изображения и добавлять преобразования, такие как scale (), rotate (), translate () и т. Д.

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

Шаги по созданию базовой игры со змейкой:

Изготовление холста

Первый шаг - создать элемент ‹canvas› и установить его размеры. Фон поверхности рисования, то есть элемент ‹canvas›, можно установить с помощью методов CSS или JavaScript.

Настройка движения

На этом этапе холст настраивается для выполнения движений в игре. Для этого мы очищаем область холста перед отображением следующего положения элементов (змея, фрукты и т. Д.), Обновляем их координаты, а затем снова показываем их, и этот процесс повторяется до тех пор, пока игра не закончится. Это достигается с помощью метода JavaScript window.setInterval (function, миллисекунды). Этот метод повторяет заданную функцию в каждом заданном интервале времени. Время указывается в миллисекундах.

В этой игре функция, определенная в window.setInterval, в основном выполняет три функции. Сначала он рисует фрукт в каком-то месте. Во-вторых, он обновляет положение змеи и отображает ее. Затем он проверяет, съела ли змея плод, и обновляет положение фруктов и выставляет оценки в соответствии с этим.

function main() {
//update state of game and display changes after specified interval
interval = window.setInterval(() => {
context.clearRect(0, 0, 500, 500);
drawFruit();
moveSnakeForward();
drawSnake();
//check if snake eats the fruit - increase size of its tail
and find new fruit position
if (snakeHeadX === fruitX && snakeHeadY === fruitY) {
totalTail++;
fruitPosition();
}
}, 200);
}

Создание приемов для рисования змеи

Это достигается созданием двух функций: drawSnakeHead () и drawSnakeBody (). Змея нарисована с использованием координат x и y каждой части ее тела, где x и y представляют верхний левый угол этой части.

В методе drawSnakeHead () переменные snakeHeadX и snakeHeadY сохраните значения x и y головы змеи соответственно. Здесь метод context.arc используется для рисования круга для части головы. Глаза Змеи можно нарисовать аналогичным образом, выбрав соответствующие координаты. Переменная «масштаб» хранит количество пикселей, которое занимает каждая часть тела змеи.

function drawSnakeHead(color) {
context.beginPath();
context.arc(snakeHeadX+scale/2, snakeHeadY+scale/2, scale/2,
0, 2 * Math.PI);
context.fillStyle = color;
context.fill();
}

Массив tail [] хранит координаты каждой части хвоста. Функция drawSnakeBody () содержит цикл, который итеративно рисует каждую часть хвоста с использованием массива «tail». Здесь переменная tailRadius просто используется для увеличения размера змеиного хвоста от задней части к передней. Итак, если длина хвоста равна 4, змея выглядит так:

function drawSnakeTail() {
let tailRadius = scale/4;
for (i = 0; i < tail.length; i++) {
tailRadius=tailRadius+((scale/2-scale/4)/tail.length);
context.beginPath();
context.fillStyle = "#6c2c3a";
context.arc((tail[i].tailX+scale/2), (tail[i].tailY+scale/2), tailRadius, 0, 2 * Math.PI);
context.fill();
}
}

Затем две указанные выше функции вызываются в методе drawSnake (), который выполняется в функции window.setInterval (). .

Функция moveSnakeForward () перемещает координаты хвоста и головы змеи в следующую позицию. Переменные xSpeed ​​ и ySpeed ​​ представляют движение в определенном направлении, т. Е. Если змея движется горизонтально, xSpeed ​​ будет равно 'scale' (положительное для правого и отрицательное для левого направления), а ySpeed ​​ будет равно нулю. наоборот. Итак, новое значение головы змеи присваивается с использованием этих переменных.

function moveSnakeForward() {
tail0=tail[0];
for (let i = 0; i < tail.length - 1; i++) {
tail[i] = tail[i + 1];
}
tail[totalTail - 1] = { tailX: snakeHeadX, tailY: snakeHeadY };
snakeHeadX += xSpeed;
snakeHeadY += ySpeed;
}

Перемещение змеи в зависимости от направления

Создан метод изменения направления головы змеи в зависимости от клавиши, нажатой игроком. Функция changeDirection () использует регистр переключателя и принимает сведения о нажатой клавише со стрелкой с помощью события «keydown» для изменения направления. Например, если нажата клавиша со стрелкой вверх:

switch (directionVar) {
case "Up":
//move "up" only when previous direction is not "down"
if (previousDir !== "Down") {
direction=directionVar;
xSpeed = 0;
ySpeed = scale * -1;
}
Break;
//similar cases for other directions
}

Переменная directionVar содержит подробную информацию о клавише, нажатой игроком. Предыдущее направление сохраняется в переменной previousDir. Когда змея движется вверх (вертикальное направление), xSpeed ​​ становится 0 (горизонтальное движение отсутствует), а ySpeed ​​ к отрицательному. Подобные случаи можно определить для других направлений, выбрав соответствующее значение для xSpeed ​​ и ySpeed ​​.

Создание фруктов

Метод generateCoordinates () генерирует случайные значения x и y в пределах высоты и ширины холста, которые можно использовать для положения фруктов. В этом месте можно создать квадрат с помощью метода fillRect (). В качестве альтернативы в это место можно вставить изображение фруктов с помощью внутреннего метода drawImage ().

Проверка столкновения

В каждом интервале необходимо проверять, не столкнулась ли змея с границами поверхности или с самим хвостом (как показано в приведенном ниже коде).

//check snake's collision
function checkCollision() {
let tailCollision=false, boundaryCollision=false;
//with its own tail
for (let i = 0; i < tail.length; i++) {
if (snakeHeadX == tail[i].tailX && snakeHeadY == tail[i].tailY) {
tailCollision=true;
}
}
//with boundaries
if(snakeHeadX >= canvas.width || snakeHeadX < 0 || snakeHeadY >= canvas.height || snakeHeadY < 0){
boundaryCollision=true;
}
return (tailCollision || boundaryCollision);
}

Вышеупомянутый метод вызывается в функции drawSnake () следующим образом:

//display snake
function drawSnake() {
drawSnakeHead("#7d4350");
drawSnakeTail();
if (checkCollision()) {
clearInterval(gameInterval);
setTimeout(()=>{
scoreModal.textContent = totalTail;
$('#alertModal').modal('show');
modalBtn.addEventListener("click", ()=>{
context.clearRect(0, 0, 500, 500);
score.innerText = 0;
   });
  }, 1000);
 }
}

Если происходит столкновение, игроку отображается сообщение, содержащее текст «Игра окончена» вместе с окончательным счетом. Здесь для этой цели используется модальный файл начальной загрузки. Текст элемента ‹span› (в модальном теле) с идентификатором 'scoreModal' установлен на итоговая оценка выглядит следующим образом:

scoreModal.textContent = totalTail;

Затем это модальное окно отображается на экране с помощью jQuery. Метод clearInterval () останавливает определенный интервал обновления холста (положение змеи, фруктов и т. Д.).

Это дает обзор методов создания базовой игры в змейку.

Чтобы увеличить сложность игры, подобным образом можно создать препятствия для змеи. Такие функции, как приостановка и возобновление игры, также могут быть добавлены нажатием клавиши пробела с помощью clearInterval () для приостановки игры и вызова main ( ) снова, чтобы возобновить игру при альтернативном нажатии клавиши пробела.

Полный код см. На GitHub.

Здесь вирус отображается в случайных местах через определенный интервал. Игра заканчивается, когда змея съедает ее. Создайте свою игру и наслаждайтесь. 🤗

Свяжитесь с нами через Instagram Twitter LinkedIn

Или отправьте нам электронное письмо ✉️ на [email protected].

Ознакомьтесь с другими нашими блогами здесь.