Как написать HTML5 игру Змейка на JavaScript. Урок 2 — вывод изображения на canvas

Добро пожаловать на второй урок нашего курса!
На этом уроке мы устанавливаем фоновое изображение нашей игры.

1. Подготовка

В этом курсе мы не будем использовать ES6 классы, но тем не менее синтаксис ES6 будем стараться применять там, где это возможно. А также мы будем практиковать объектно-ориентированный подход и использовать классические JS объекты, создаваемые через литерал.

Для начала нам потребуется один главный глобальный объект:

let game = {};

Внутри этого объекта мы будем реализовывать всю игровую логику.
В первую очередь от этого объекта нам потребуется запустить игру поэтому реализуем метод start:

let game = {
start: function() {
}
};

Вызовем этот метод после описания объекта game:

game.start();

2. Получаем канвас и контекст для отрисовки

Теперь сосредоточимся на нашей текущей задаче.
Рендерить графику на экране нам поможет html5 тег canvas.
Именно это так содержит необходимый программный интерфейс, то есть набор методов, который мы можем использовать для рендеринга изображений.
Используем DOM, чтобы получить этот элемент в коде:

let game = {
start: function() {
let canvas = document.getElementById("mycanvas");
}
};

В переменной canvas теперь хранится DOM объект, который содержит свои методы и свойства. Нас интересует метод getContext этого объекта. Именно этот метод будет возвращать программный интерфейс, о котором мы говорили выше и который позволит нам работать с графикой.
Вызовем этот метод с параметром "2d", чтобы получить контекст для двухмерной графики:

let game = {
start: function() {
let canvas = document.getElementById("mycanvas");
let ctx = canvas.getContext("2d");
}
};

3. Получаем объект изображения

Теперь необходимо получить само фоновое изображение в виде объекта, с которым мы можем работать в JS.
Вызовем конструктор new Image чтобы создать новое пустое изображение:

let background = new Image();

Присвоим значение свойству src, чтобы указать путь до файла с изображением:

background.src = "img/background.png";

4. Выводим изображение на канвас

Используем метод контекста drawImage для отрисовки полученного в виде объекта изображения:

ctx.drawImage(background, 0, 0);

В качестве второго и третьего параметра передаем координаты канваса, с которых требуется начать отрисовку.
Считается что отсчет координат на канвасе начинается с левого верхнего угла по возрастанию вправо вниз.
Таким образом левый вверх верхний угол имеет координаты [0, 0], а правый нижний угол имеет максимальные координаты по оси x и по оси y, в нашем случае: [640, 360].
Итак, указываем нули в качестве координат x и y и передаем их вторым и третьим параметрами в вызов метода drawImage.
Но одного данного метода еще не достаточно, что вывести изображение.

Суть drawImage заключается в том, чтобы только запланировать отрисовку указанного изображения, но не нарисовать его. Реальную отрисовку текущего кадра выполняет метод window.requestAnimationFrame
А в качестве параметра в этот метод необходимо передать колбек функцию, которая будет выполнена непосредственно до перерисовки кадра. Таким образом, запланировав изображения нового кадра в колбек функции, выполним реальную отрисовку:

window.requestAnimationFrame(() => {
ctx.drawImage(background, 0, 0);
});

5. Отслеживаем факт загрузки картинки

Осталось исправить только одну ошибку.
В данный момент запрос на отрисовку нового кадра запускается сразу после создания изображения. Но загрузка изображения происходит асинхронно и в реальности требуется некоторое время, чтобы реальный файл загрузился в браузер на клиент.
Таким образом, если мы просим браузер вывести новый кадр, мы хотим быть уверены в том, что изображение к этому моменту точно загружено и доступно для отрисовки. Для этого отследим факт загрузки через событие load и в качестве колбека данного события опишем функцию, в которой и вызовем код отрисовки:

background.addEventListener("load", () => {
window.requestAnimationFrame(() => {
ctx.drawImage(background, 0, 0);
});
});

Весь код урока

let game = {
start: function() {
let canvas = document.getElementById("mycanvas");
let ctx = canvas.getContext("2d");

let background = new Image();
background.src = "img/background.png";
background.addEventListener("load", () => {
window.requestAnimationFrame(() => {
ctx.drawImage(background, 0, 0);
});
});

}
};

game.start();

Вот теперь код работает корректно и задачу можно считать успешно выполненной!
До встречи наследующем уроке, в котором мы на основе данного кода будем разрабатывать полноценный прелоадер ассетов.

Git: https://github.com/bolotnikov/snake

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

Leave a reply:

Your email address will not be published.

Site Footer