Предисловие от автора перевода.
Итак, я наконец-то подготовил перевод статьи Михала Будзинского открывающей нам новый web-стандарт HTML5. Этот стандарт еще не имеет утвержденной спецификации и представлен на сайте w3.org только как рабочий черновик, но уже активно продвигается производителями браузеров. Новшества, вносимые новой версией HTML (язык разметки гипертекстов) сближают его с языками программирования. Благодаря активному развитию социальных сетей, «облачных» сервисов и т.п. все яснее прослеживается необходимость улучшения интеграции мультимедийного контента и новый тэг <canvas> стал одним из решений данного вопроса представленный консорциумом.
Движок игры написан на JavaScript и те, кто еще не знаком с этим языком программирования найдут здесь также замечательные примеры для его начального освоения.
Введение.
StH - очень простой клон Doodle Jump, но чтобы быть до конца честным, я был вдохновлен Icy Tower. Ну да ладно.
Цель игры состоит в том, чтобы управлять маленьким ангелом и скакать на двух видах платформ - оранжевые (обычные) и зеленые (трамплины). Игра заканчивается, когда ангел падает за нижний край экрана.
Я создал эту игру за 8 часов и позже, когда довольно долго играл, я обнаружил немного ошибок, так что в этом уроке, я хочу исправить их все. Давайте приступим!
Фон.
Поскольку вся игра, включая изображения и сценарии (скрипты), не должна быть больше 10КБ, я не захотел использовать растровое изображение на фоне. Гораздо экономичнее рисовать используя функции рисования <canvas>.
Прежде всего, мы нуждаемся в небольшом HTML, ничего особенного, только один <canvas> элемент с некоторым уникальным id, немного CSS и несуществующий, пока еще, game.js:
<html>
<head>
<title> Простая игра с HTML5 Canvas </ title>
<style>
body {margin:0px; padding:0px; text-align: center}
canvas {outline:0; border:1px solid # 000; margin: 0 auto}
</ style>
</ head>
<body>
<canvas id='c'></ canvas>
<script src="game.js"></ script>
</ body>
</ html>
Это и есть весь HTML, который нам понадобится в течение этого урока. Хорошо, теперь давайте создавать Javascript. Прежде всего мы должны создать немного глобальных (хотя, я знаю что это Глобальное зло =) переменных и изменить атрибуты (свойства) <canvas>. Этого будет достаточно:
var width = 320, //ширина canvas
height = 500, //высота canvas
c = document.getElementById('c'), //сам canvas
ctx = c.getContext('2d');
//двумерный контектс canvas (сейчас только он поддерживается всеми
//браузерами)
c.width = width;
c.height = height;
//устанавливаем размеры canvas
Первое, что важно понять про <canvas>, это то, что невозможно просто перемещать объекты на его поверхности. Нужно, обязательно, на каждом кадре его очищать, целиком или частично. Поэтому давайте создадим функцию очистки – clear():
var clear = function(){
ctx.fillStyle = '#d0e7f9';
//выбираем цвет заливки (чудесный голубой)
//Использование clearRect() вызывало ошибку, в 2-х строках ниже показан
//старый вариант
//ctx.clearRect(0, 0, width, height);
//очистка экрана
ctx.beginPath();
//запускаем рисование
ctx.rect(0, 0, width, height);
//рисуем прямоугольник из точки (0, 0) до (width, height) заполняя весь наш
//холст <canvas>
ctx.closePath();
//заканчиваем рисование
ctx.fill();
//заполняем прямоугольник цветом выбранным ранее
}
Одноцветный фон скучен как ад, так что давайте нарисуем несколько облаков на нем. Скорее не правильные облака, а простые, полупрозрачные круги, подражающие облакам. Круги мы будем рисовать в случайных местах холста, каждый с различным размером и прозрачностью. Мы будем держать всю информацию о кругах в 2-ом массиве (в JS их нет, но лучший путь к решению этой проблемы помещение одного массива в другой).
var howManyCircles = 10, circles = [];
for (var i = 0; i < howManyCircles; i++)
circles.push([Math.random() * width, Math.random() * height, Math.random() * 100, Math.random() / 2]);
//добавляем информацию о кругах
//в массив 'circles'. Это x и y позиция,
//радиус в диапазоне 0-100 и прозрачность
//в диапазоне 0-0.5 (0 это абсолютно прозрачно, 1 непрозрачно)
var DrawCircles = function(){
for (var i = 0; i < howManyCircles; i++) {
ctx.fillStyle = 'rgba(255, 255, 255, ' + circles[i][3] + ')';
//белый цвет с прозрачностью в rgba
ctx.beginPath();
ctx.arc(circles[i][0], circles[i][1], circles[i][2], 0, Math.PI * 2, true);
//arc(x, y, radius, startAngle, endAngle, anticlockwise)
ctx.closePath();
ctx.fill();
}
};
Хорошо, но скучновато. Почему облака стоят на месте? Давайте сделаем маленькую функцию с одним аргументом, которая сдвигает облака вниз на заданное число пикселей, и, когда определенный круг скрывается за пределами холста, он перемещается наверх с изменением координаты X, радиуса и прозрачности:
var MoveCircles = function(deltaY){
for (var i = 0; i < howManyCircles; i++) {
if (circles[i][1] - circles[i][2] > height) {
//круг достигший нижнего края
//меняет параметры
circles[i][0] = Math.random() * width;
circles[i][2] = Math.random() * 100;
circles[i][1] = 0 - circles[i][2];
circles[i][3] = Math.random() / 2;
} else {
//сдвигаем круг на deltaY пикселей вниз
circles[i][1] += deltaY;
}
}
};
Теперь, не в последнюю очередь, давайте создадим основной цикл игры и подключим в нем все, что уже создали. Каждый кадр будет очищать экран, перемещать круги на 5px вниз, рисовать их и после 1/50 секунды вызывать следующий кадр. Я использую два setTimeouts вместо одного setInterval, хотя незнаю почему:). Вроде бы раньше были некоторые проблемы с производительностью в IE, что ли. И не забудьте добавить gLoopв глобальные переменные, объявленные вначале.
var width = 320,
//ширина холста <canvas>
height = 500,
//высота холста <canvas>
gLoop,
(...) //остальная часть кода находится здесь
var GameLoop = function(){
clear();
MoveCircles(5);
DrawCircles();
gLoop = setTimeout(GameLoop, 1000 / 50);
}
GameLoop();
Благодарю Луиса Гирибоуна за комментарии к уроку. Он помог разобраться в чем отличие setTimeOut от setInterval. SetInterval запускает функцию переданную ему в аргументе не дожидаясь окончания предыдущей итерации, а setTimeOut ждет ее завершения даже если вышло время переданное в качестве второго аргумента.
Так же хочу поблагодарить пользователя под ником Ped7g за выявленные ошибки.
Результат этой части урока можно посмотреть по адресу: http://jsbin.com/odoho3, а скачать исходники тут: http://github.com/michalbe/Simple-game-with-HTML5-Canvas
Копирайты.
Автор: Михал Будзинский https://twitter.com/#!/@michalbe
Автор перевода: Андрей Семенов https://twitter.com/#!/a_semenov79
HDR фильтр на canvas http://siteacademy.ru/index.php/htmldev/38-html/html5-image-effects-html-canvas
ReplyDelete