Я всегда любил веб-игры; их просто весело делать, их легко кодировать (в основном), и есть кое-что действительно приятное в том, насколько доступна игра, когда пользователю просто нужно нажать на ссылку, чтобы начать играть.
Ajax и перемещение элементов dom повсюду развлекали, но ограничивались тем, какой опыт вы могли бы создать. Для разработчиков игр все меняется и быстро. HTML5 вводит кучу новых возможностей для разработки игр исключительно в браузере, и производители браузеров борются за то, чтобы стать лучшей платформой для новых стандартов.
Таким образом, с точки зрения разработчика игр, все идет в правильном направлении: аппаратное ускорение 2D и 3D, высокопроизводительные движки javascript, встроенные отладчики и профилировщики, и, возможно, самое главное, производители браузеров, которые активно участвуют в гонках, чтобы быть лучшими для серьезных разработка игр.
Таким образом, инструменты становятся пригодными для использования, браузеры способны, а производители слушают, мы можем просто делать классные игры, верно? Ну, в основном.
Разработка игр на HTML5 / Javascript все еще находится на ранней стадии, и здесь следует избегать ловушек, а также выбирать, какую технологию использовать.
В этой статье я расскажу о некоторых вариантах, которые необходимо сделать при разработке 2D-игр, и, надеюсь, дам вам несколько идей по разработке собственных игр с использованием HTML5.
Основы
Первый вопрос, на который вам нужно ответить, — использовать ли тег HTML5 Canvas для рисования изображений (граф сцены) или манипулировать элементами DOM.
Чтобы делать 2D-игры с использованием DOM, вы в основном настраиваете стили элементов динамически, чтобы перемещать их по странице. Хотя в некоторых случаях манипуляции с DOM хороши, я сосредоточусь на использовании холста HTML5 для графики, поскольку он наиболее гибок для игр в современном браузере.
Если вы беспокоитесь о совместимости с более старыми браузерами и canvas, ознакомьтесь с excanvas ( http://excanvas.sourceforge.net/ ).
Настройка страницы
Для начала вам нужно создать HTML-страницу, содержащую тег canvas:
<! doctype html> <HTML> <Голова> <Название> </ название> </ HEAD> <body style = 'position: absolute; обивка: 0; Маржа: 0; высота: 100%; ширина: 100% '> <canvas id = "gameCanvas"> </ canvas> </ Body> </ Html>
Если вы загрузите это, вы будете вознаграждены, ну, ничего особенного. Это потому, что, хотя у нас есть тег canvas, мы ничего не нарисовали на нем. Давайте добавим несколько простых вызовов canvas, чтобы нарисовать несколько блоков.
<Голова> <Название> </ название> <script type = 'text / javascript'> var canvas = null; function onload () { canvas = document.getElementById ('gameCanvas'); var ctx = canvas.getContext ("2d"); ctx.fillStyle = '# 000000'; ctx.fillRect (0, 0, canvas.width, canvas.height); ctx.fillStyle = '# 333333'; ctx.fillRect (canvas.width / 3, canvas.height / 3, canvas.width / 3, canvas.height / 3); } </ Скрипт> </ HEAD> <body onload = 'onload ()' ...
В этом примере я добавил привязку события onload к тегу body, а затем реализовал функцию для захвата элемента canvas и рисования некоторых блоков. Пока все достаточно просто.
Коробки хороши, но вы заметите, что холст не занимает всю область окна браузера. Чтобы приспособить это, мы можем установить его размер, добавив стиль ширины и высоты к тегу canvas. Я предпочитаю сохранять динамичность, регулируя размер в зависимости от размера элемента документа, в котором содержится холст.
var canvas = null; function onload () { canvas = document.getElementById ('gameCanvas'); canvas.width = canvas.parentNode.clientWidth; canvas.height = canvas.parentNode.clientHeight; ...
Перезагрузите, и вы увидите холст, занимающий весь экран. Сладкий.
Пойдем дальше, давайте справимся с изменением размеров холста, если пользователь изменяет размер окна браузера.
var canvas = null; function onload () { canvas = document.getElementById ('gameCanvas'); размер (); } function resize () { canvas.width = canvas.parentNode.clientWidth; canvas.height = canvas.parentNode.clientHeight; var ctx = canvas.getContext ("2d"); ctx.fillStyle = '# 000000'; ctx.fillRect (0, 0, canvas.width, canvas.height); ctx.fillStyle = '# 333333'; ctx.fillRect (canvas.width / 3, canvas.height / 3, canvas.width / 3, canvas.height / 3); }
И добавьте вызов onresize к тегу body.
<body onresize = 'resize ()' ...
Теперь, если вы измените размер браузера, прямоугольники будут хорошо следовать.
Загрузка графики
Большинству игр понадобятся анимированные спрайты, поэтому давайте добавим немного графики.
Сначала вам нужно добраться до ресурса изображения. Поскольку мы собираемся рисовать его из javascript, я считаю, что имеет смысл объявить там изображение и затем установить его атрибут src в качестве URL-адреса изображения, которое вы хотите загрузить. Пожалуйста, загрузите этот файл изображения, который адаптирован из SpriteLib GPL : simba.png
var img = null; function onload () { ... img = новое изображение (); img.src = 'simba.png'; }
Затем вы можете нарисовать изображение, добавив его в метод resize:
ctx.drawImage (img, canvas.width / 2 - (img.width / 2), canvas.height / 2 - (img.height / 2));
Если вы затем перезагрузите страницу, в большинстве случаев вы увидите изображение. Я говорю в большинстве случаев, потому что это зависит от того, насколько быстро работает ваша машина, и не кэшировал ли уже браузер изображение. Это потому, что метод resize вызывается между тем, когда вы начали загружать изображение (устанавливая его атрибут src) и когда браузер уже готов к работе. С одним или двумя изображениями вам это может сойти с рук, но как только ваша игра расширится, вам придется подождать, пока все изображения будут загружены, прежде чем предпринимать какие-либо действия. Чтобы подождать, добавьте слушателя уведомлений к изображению, чтобы получить обратный вызов, когда изображение будет готово. Мне пришлось немного изменить положение вещей, чтобы все это заработало, поэтому вот полный обновленный код:
var canvas = null; var img = null; var ctx = null; var imageReady = false; function onload () { canvas = document.getElementById ('gameCanvas'); ctx = canvas.getContext ("2d"); img = новое изображение (); img.src = 'images / simba.png'; img.onload =loaded (); размер (); } функция загружена () { imageReady = true; перерисовывать (); } function resize () { canvas.width = canvas.parentNode.clientWidth; canvas.height = canvas.parentNode.clientHeight; перерисовывать (); } function redraw () { ctx.fillStyle = '# 000000'; ctx.fillRect (0, 0, canvas.width, canvas.height); if (imageReady) ctx.drawImage (img, canvas.width / 2 - (img.width / 2), canvas.height / 2 - (img.height / 2)); }
И результаты должны быть:
Это изображение показывает 6 бегущих кадров маленького котенка-вампира (ну, я думаю, это так). Чтобы оживить спрайт, нам нужно рисовать каждый кадр по одному.
Спрайт Анимация
Вы можете нарисовать один кадр, используя исходные параметры вызова drawImage. По сути, только рисование ограниченной части исходного изображения. Таким образом, чтобы нарисовать только первый кадр, используйте расширенную версию drawImage, которая позволяет вам указать прямоугольник в исходном изображении. Так как наша кошачья анимация состоит из 6 кадров размером 96 х 96 пикселей, мы можем сделать:
ctx.drawImage (img, 0, 0, 96, 54, canvas.width / 2 - 48, canvas.height / 2 - 48, 96, 54);
Ключевым моментом здесь являются стартовые 0, 0, 96, 54
Это ограничивает нарисованное изображение только первым кадром нашей анимации кошки. Я также настроил центрирование так, чтобы оно основывалось на одном кадре (48 с), а не на полном размере изображения, содержащем все шесть кадров.
Теперь самое интересное. Чтобы анимация работала, нам нужно отследить, какой кадр нарисовать, а затем с течением времени увеличить номер кадра. Для этого нам нужно перейти со статической страницы на страницу, которая периодически повторяется.
Давайте начнем делать вещи старомодным способом. Добавьте интервальный таймер с временем цикла, эквивалентным 60 кадрам в секунду (1000 мс, деленное на 60). Чтобы убедиться, что мы запускаем цикл анимации только после загрузки изображения, поместите вызов в загруженную функцию:
функция загружена () { imageReady = true; setTimeout (обновление, 1000/60); }
Добавление функции обновления может затем переместить кадр вперед и вызвать перерисовку:
var frame = 0; функция update () { перерисовывать (); кадр ++; if (frame> = 6) frame = 0; setTimeout (обновление, 1000/60); }
После того, как тираж и кадр были продвинуты, тайм-аут устанавливается снова.
Затем измените рисованное изображение, чтобы переместить исходное окно в соответствии с тем, какой кадр мы хотим нарисовать (ключевой частью является исходная позиция X, установленная на кадр, умноженный на размер кадра (в данном случае frame * 96):
function redraw () { ctx.fillStyle = '# 000000'; ctx.fillRect (0, 0, canvas.width, canvas.height); if (imageReady) ctx.drawImage (img, frame * 96, 0, 96, 54, canvas.width / 2 - 48, canvas.height / 2 - 48, 96, 54); }
И результат:
Наша злая нежить-вампир-котенок живет! На суперкатах даже скорости.
Теперь у нас есть анимация, мы сделаем некоторые улучшения во второй части этой статьи, послезавтра.
Эта статья первоначально появилась на BuildNewGames.com , совместная работа команд в Bocoup и Internet Explorer.