Обработка пользовательского ввода в играх с помощью технологии HTML5 Canvas

Определение событий клавиатуры, мыши и сенсорного экрана для разработки игр

Оказавшись в мире игр HTML5, легко недооценить сложность управления событиями клавиатуры, мыши и сенсорного экрана. В этой статье рассматриваются основные методы отработки взаимодействия с пользователем в играх на базе HTML Canvas. Читатель узнает, как обрабатывать события клавиатуры и мыши, как изменить поведение Web-браузера по умолчанию в отношении событий и как передавать события логическим представлениям игровых объектов. Он также научится обрабатывать события таких мобильных устройств, как iPhone и iPad.

Кевин Мут, инженер-программист, The Nerdery

Фото Кевина МутаКевин Мут (Kevin Moot) интересуется компьютерной графикой с момента появления на его машине Apple IIe (с ее широким спектром из шести цветов и невероятным разрешением 280x192) таких игр, как "Мальчик-с-пальчик". Работал с технологией Canvas, входящей в HTML5, при создании нескольких передовых Web-сайтов и включает в список своих специализаций HTML/CSS, JavaScript и .NET. В настоящее время ― разработчик интерактивного программного обеспечения в компании The Nerdery.



11.12.2012

Введение

Разработчики, знакомые с Flash и Silverlight, бывают удивлены тем, что приложения, написанные для HTML5 Canvas, не предоставляют специальных средств для обработки пользовательского ввода. По существу, с самых первых дней существования Web-браузеров с поддержкой JavaScript пользовательский ввод HTML предусматривает применение системы обработки событий, встроенной в браузеры; в HTML5 нет никаких специальных средств для обнаружения и обработки пользовательского ввода. Браузер может, например, обеспечить низкоуровневую обратную связь с указанием координат (x, y), выбранных пользователем, и не более того.

Часто используемые сокращения

  • CSS: Cascading style sheet / Каскадная таблица стилей
  • DOM: Document Object Model
  • HTML: HyperText Markup Language

Обработка взаимодействий с пользователем ничем не отличается от ее реализации в любой другой низкоуровневой игровой архитектуре. В Canvas нет встроенных абстракций, уведомляющих о том, что пользователь взаимодействовал с тем или иным отображаемым объектом. Это обеспечивает высокую степень низкоуровневого контроля над тем, как вы будете обрабатывать эти события. Имея в своем распоряжении разнообразные функции браузера, можно настроить обработку событий для достижения максимальной эффективности в соответствии с конкретным приложением — не будучи привязанным к конкретной реализации.

В этой статье рассматриваются методы обработки данных взаимодействия с пользователем в играх на базе HTML Canvas. Примеры иллюстрируют способы обработки событий клавиатуры, мыши и сенсорного экрана. Также рассматриваются стратегии передачи событий игровых объектов и совместимость с мобильными устройствами.

Исходный код примеров, приведенных в этой статье, содержится в разделе Загрузки.


Типы событий

Взаимодействие с пользователем полностью управляется традиционной моделью прослушивателя событий браузера. С появлением HTML5 ничего не изменилось; это та же модель событий, которая используется с первых дней Netscape Navigator.

По сути, интерактивное приложение или игру можно считать сочетанием модели событий браузера для пользовательского ввода и Canvas для графического вывода. Между ними нет никакой логической связи, если вы не создадите ее сами.

Можно воспользоваться тем, что прослушиватели событий допускается связывать с самим элементом <canvas>. Поскольку элемент <canvas> ― это просто элемент уровня блока, с точки зрения браузера это ничем не отличается от присоединения прослушивателей событий к <div> или любому другому элементу уровня блока.


События клавиатуры

Простейшим типом событий для прослушивания и обработки являются события клавиатуры. Они не зависят от элемента Canvas или положения курсора. Для событий клавиатуры достаточно прослушивать события keydown, keyup и keypress на уровне документа.

Прослушивание событий клавиатуры

Модель прослушивателя событий может варьироваться в зависимости от реализации браузера, поэтому лучше всего использовать библиотеку для нормализации обработки событий. В следующих примерах для привязки событий используется библиотека jQuery. Как правило, это самый простой способ приступить к работе, но универсальность библиотеки jQuery, поддерживающей устаревшие браузеры, может неблагоприятно сказаться на производительности. Другая популярная библиотека, написанная специально для ускорения кроссбраузерной обработки событий клавиатуры, ― Kibo (см. раздел Ресурсы).

Листинг 1 иллюстрирует прослушивание событий клавиатуры и вызов соответствующих действий в зависимости от того, какая клавиша нажата.

Листинг 1. Обработка событий клавиатуры
$(document.body).on('keydown', function(e) {
    switch (e.which) {
        // код клавиши стрелки влево
        case 37:
            console.log('left arrow key pressed!');
            break;

        // код клавиши стрелки вправо
        case 39:
            console.log('right arrow key pressed!');
            break;
    }
});

Если приложение работает в среде Web-браузера, важно учитывать принятые в ней сочетания клавиш. Хотя технически можно переопределить поведение общепринятых комбинаций клавиш, отменив поведение браузера по умолчанию (например, для комбинации клавиш control-r), это настоятельно не рекомендуется.


События мыши

События мыши сложнее событий клавиатуры. Нужно знать положения элемента Canvas в окне браузера, а также положение курсора пользователя.

Прослушивание событий мыши

С помощью свойств e.pageX и e.pageY легко получить положение мыши по отношению ко всему окну браузера. В этом случае начало координат (0,0) расположено в левом верхнем углу окна браузера.

Обычно если курсор не находится в области Canvas, пользовательский ввод не имеет значения. Поэтому началом координат (0,0) лучше считать верхний левый угол элемента Canvas. В идеале лучше работать в локальной системе координат, относящейся к области Canvas, а не с глобальной, относящейся ко всему окну браузера.

Стратегии обработки событий мыши

Для преобразования глобальных координат окна в локальные координаты Canvas нужно выполнить следующие действия.

  1. Вычислить положение (x, y) элемента DOM Canvas на странице.
  2. Определить глобальное положение мыши по отношению к документу в целом.
  3. Расположить начало координат (0,0) в верхнем левом углу элемента Canvas и эффективно преобразовать глобальные координаты в относительные, используя смещение между глобальным положением мыши, рассчитанным на шаге 2, и положением Canvas, рассчитанным на шаге 1.

На рисунке 1 приведен пример информации, которую нужно получить, исходя из глобальной системы координат.

Рисунок 1. Положение мыши в глобальных координатах
Положение мыши в глобальных координатах

На рисунке 2 показан результат преобразования положения мыши в локальную систему координат.

Рисунок 2. Положение мыши после преобразования в локальную систему координат
Положение мыши в локальных координатах

В листинге 2 показан метод определения локальных координат мыши. Предполагается, что элемент Canvas определен в разметке следующим образом: <canvas id="my_canvas"></canvas>.

Листинг 2. Обработка событий мыши
var canvas = $('#my_canvas');

// вычисление положения (x, y) элемента Canvas DOM на странице

var canvasPosition = {
    x: canvas.offset().left,
    y: canvas.offset().top
};

canvas.on('click', function(e) {

    // использование pageX и pageY для получения положения указателя мыши
    // относительно окна браузера

    var mouse = {
        x: e.pageX - canvasPosition.x,
        y: e.pageY - canvasPosition.y
    }

    // теперь есть локальные координаты,
    // начало которых  (0,0) расположено в
    // верхнем левом углу элемента canvas
});

Нежелательное поведение браузера

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

На рисунке 3 приведен пример того, что может произойти, если пользователь нажимает на изображение и буксирует его в браузере. Поведение браузера по умолчанию имеет смысл для перетаскивания в приложениях, но в игре оно только мешает.

Рисунок 3. Поведение браузера по умолчанию при перетаскивании изображения
Поведение браузера по умолчанию при перетаскивании изображения

Во всех обработчиках событий добавляйте строку preventDefault() с возвратом из этой функции значения false. Код, приведенный в листинге 3, проделывает этот трюк, предотвращая действие по умолчанию и наложение событий.

Листинг 3. Предотвращение поведения по умолчанию
canvas.on('click', function(e) {
    e.preventDefault();

    var mouse = {
        x: e.pageX - canvasPosition.x,
        y: e.pageY - canvasPosition.y
    }

    //происходит изменение положения мыши

    return false;
});

Даже при наличии кода, приведенного в листинге 3, можно столкнуться с нежелательными побочными эффектами, когда пользователь инициирует событие перетаскивания элемента DOM, такими как появление I-образного курсора, выбор текста и т.п. Проблема событий перетаскивания чаще возникает с изображениями, но лучше применить к элементу Canvas этот метод, чтобы предотвратить перетаскивание и выбор. В листинге 4 показано правило CSS для предотвращения побочных эффектов выбора путем небольшого вкрапления CSS.

Листинг 4. Рекомендуемые стили для предотвращения выбора
image, canvas {
    user-select: none;
    -ms-user-select: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -webkit-touch-callout: none;
    -webkit-user-drag: none;
}

Переопределение поведения рабочего стола

Обычно хорошая идея ― переопределить события перетаскивания и выбора, чтобы поведение браузера по умолчанию не высовывало свою уродливую голову.

В коде, приведенном в листинге 5, библиотека jQuery намеренно не используется для подключения событий. jQuery не обрабатывает события ondragstart и onselectstart должным образом (обработчики могут не сработать, если они подключены с помощью jQuery).

Листинг 5. Отмена событий перетаскивания и выбора
var canvasElement = document.getElementById('my_canvas');

// ничего не делать в обработчике событий, за исключением отмены события
canvasElement.ondragstart = function(e) {
    if (e && e.preventDefault) { e.preventDefault(); }
    if (e && e.stopPropagation) { e.stopPropagation(); }
    return false;
}

// ничего не делать в обработчике событий, за исключением отмены события
canvasElement.onselectstart = function(e) {
    if (e && e.preventDefault) { e.preventDefault(); }
    if (e && e.stopPropagation) { e.stopPropagation(); }
    return false;
}

Переопределение поведения мобильных устройств

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

Поведение масштабирования можно предотвратить, добавив user-scalable=no в метатег viewport. Пример:

<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1" />

Чтобы отключить любые перемещения документа или окна при использовании жестов, добавьте в файл document.body прослушиватели событий, приведенные в листинге 6. Это отменит любое поведение браузера по умолчанию при касании пользователя где-то за пределами области Canvas или игры.

Листинг 6. Отмена перемещения окна мобильного браузера
document.body.ontouchstart = function(e) {
    if (e && e.preventDefault) { e.preventDefault(); }
    if (e && e.stopPropagation) { e.stopPropagation(); }
    return false;
}

document.body.ontouchmove = function(e) {
    if (e && e.preventDefault) { e.preventDefault(); }
    if (e && e.stopPropagation) { e.stopPropagation(); }
    return false;
}

Передача данных игровым объектам

Для каждого типа событий, которые нужно захватывать, к Canvas должен быть подключен только один прослушиватель событий. Например, если нужно захватить события click и mousemove, просто прикрепите к Canvas прослушиватели событий single click и single mousemove. Их нужно подключить только один раз, так что это обычно делается во время инициализации приложения.

Если какую-то полезную информацию, полученную прослушивателем событий, нужно довести до сведения объектов, находящихся в области Canvas, придется создать свою собственную систему логики. В данном примере такая система отвечала бы за передачу события click или mousemove всем игровым объектам, которые связаны с обработкой одного из этих событий.

Когда каждый игровой объект узнает об одном из этих событий, он сначала должен определить, относится ли к нему данное событие click или mousemove. Если да, то объект игры должен будет определить, находятся ли координаты мыши в пределах его границ.

Стратегии вещания

Конкретная стратегия зависит от типа игры. Например, стратегия для 2D-текстуры может отличаться от стратегии для 3D-мира.

Следующие действия определяют реализацию, которая хорошо работает с простым 2D-приложением.

  1. Определение координат нажатия кнопки мыши в области Canvas.
  2. Уведомление всех игровых объектов о том, что произошло событие click с данным набором координат.
  3. Выполнение проверки нахождения курсора между координатами мыши и границами игрового объекта для каждого игрового объекта, чтобы определить, совпадают ли координаты мыши с этим объектом.

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

Обработчик события click может выглядеть как в листинге 7. В примере предполагается, что некоторая структура для отслеживания всех игровых объектов уже создана. Положение и размеры всех игровых объектов хранятся в переменной gameObjectArray

Листинг 7. Вещание обработчика событий click на игровые объекты
// Инициализация массива игровых объектов в различных позициях 
//  на экранес помощью новой переменной 
// gameObject(x, y, ширина, высота)

var gameObjectArray = [
	new gameObject(0, 0, 200, 200),
	new gameObject(50, 50, 200, 200),
	new gameObject(500, 50, 100, 100)
];

canvas.on('click', function(e) {
    var mouse = {
        x: e.pageX - canvasPosition.x,
        y: e.pageY - canvasPosition.y
    }

    // перебор всех игровых объектов с вызовом 
    // обработчика onclick для каждого из них

    for (var i=0; i < gameObjectArray.length; i++) {
        gameObjectArray[i].handleClick(mouse);
    }
});

Следующий шаг гарантирует, что каждый игровой объект сможет выполнить проверку попадания, определяя, находятся ли координаты мыши в зоне этого игрового объекта. На рисунке 4 приведен пример неудачной проверки попадания.

Рисунок 4. Щелчок вне границ объекта - неудачная проверка попадания
Щелчок вне границ объекта - неудачная проверка попадания

На рисунке 5 приведен пример успешной проверки попадания.

Рисунок 5. Щелчок в границах объекта - успешная проверка попадания
Щелчок в границах объекта - успешная проверка попадания

Можно определить класс игровых объектов, как показано в листинге 8. Тест попадания выполняется в функции onclick(), которая проверяет совпадение прямоугольного контура объекта с координатами мыши, которые передаются ей в качестве параметра.

Листинг 8. Класс игровых объектов и проверка попадания
function gameObject(x, y, width, height) {
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;

    // параметр mouse содержит координаты мыши
    this.handleClick = function(mouse) {

        // выполнение проверки попадания 
        // координат мыши внутрь контура

        if (this.x < mouse.x &&
            this.x + this.width > mouse.x &&
            this.y < mouse.y &&
            this.y + this.height > mouse.y) {

            // Проверка прошла успешно, обработать событие click!
            return true;
        }

        // Проверка попадания не удалась
        return false;
    }
}

Повышение эффективности вещания

Во многих случаях можно создать более эффективную реализацию. Например, в игре с тысячами игровых объектов хотелось бы избежать проверки каждого игрового объекта на экране при каждом щелчке.

В следующем примере специальные события jQuery используются для создания синтетических событий. Синтетическое событие обрабатывается только теми игровыми объектами, которые прослушивают данное конкретное событие. Пример

  1. Обработать событие щелчка кнопкой мыши, как описано выше, и выполнить любые необходимые преобразования (преобразование положения мыши в локальные координаты и т.п.).
  2. Вызвать синтетическое событие, содержащее в качестве параметра преобразованные координаты мыши.
  3. Любой игровой объект, обрабатывающий события click, должен настроиться на прослушивание синтетического события.

Обработчик событий мыши click изменен таким образом, чтобы просто вызвать специальное событие. Специальному событию можно присвоить любое произвольное имя. В листинге 9 он называется handleClick.

Листинг 9. Вызов специального события
canvas.on('click', function(e) {
    var mouse= {
        x: e.pageX - canvasPosition.x,
        y: e.pageY - canvasPosition.y
    }

    //вызов синтетического события, содержащего информацию о координатах мыши
    $(canvas).trigger('handleClick', [mouse]);
});

Как показано в листинге 10, класс игровых объектов тоже изменен. Вместо определения функции onclick, просто прослушивается событие handleClick. В каждом случае инициирования события handleClick любые игровые объекты, которые прослушивают это событие, запустят свои обработчики событий.

Листинг 10. Обработка специального события
function gameObject(x, y, width, height) {
    var self = this;
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;

    $(canvas).on('handleClick', function(e, mouse) {

        // выполнение проверки попадания 
        // координат мыши внутрь контура

        if (self.x < mouse.x &&
            self.x + self.width > mouse.x &&
            self.y < mouse.y &&
            self.y + self.height > mouse.y) {

            // Проверка прошла успешно, обработать событие click!

        }
    });
}

Усовершенствованная проверка попадания

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

Чтобы обрабатывать такие слои, нужно знать порядок, или глубину, каждого из наложенных игровых объектов. Canvas не обеспечивает никакого логического представления глубины, поэтому вновь придется взять бразды правления в свои руки и создать необходимую логику для обработки этой ситуации.

Чтобы ввести понятие глубины, необходимо присвоить всем игровым объектам индекс z, указывающий их глубину. Пример приведен в листинге 11.

Листинг 11. Добавление индекса z к игровому объекту
function gameObject(x, y, zIndex, width, height) {
    var self = this;
    this.x = x;
    this.y = y;
    this.zIndex = zIndex;
    this.width = width;
    this.height = height;

    //...
}

Чтобы облегчить проверку глубины, необходимо выполнить сортировку. В листинге 12 пример структуры для хранения игровых объектов отсортирован таким образом, что первым в списке значится игровой объект с самым большим значением индекса z.

Листинг 12. Сортировка массива игровых объектов
// сортировка в таком порядке, что первым значится самый большой индекс z
var sortedGameObjectArray = gameObjectArray.sort(function(gameObject1, gameObject2) {
    if (gameObject1.zIndex < gameObject2.zIndex) return true;
    else return false;        
})

Наконец, в функции click выполняется перебор всех игровых объектов в отсортированном массиве.

Как только обнаружится положительный результат проверки попадания на игровой объект, сразу же останавливаемся, чтобы распространение click не продолжалось. Если не остановить проверку, как показано в листинге 13, мы получим нежелательное поведение ― обработку события click игровыми объектами более глубоких уровней.

Листинг 13. Прерывание на успешной проверке попадания
canvas.on('click', function(e) {
    var mouse = {
        x: e.pageX - canvasPosition.x,
        y: e.pageY - canvasPosition.y
    }

    for (var i=0; i < sortedGameObjectArray.length; i++) {
        var hitTest = sortedGameObjectArray[i].onclick(mouse);

        // остановить при первой же успешной проверке попадания
        if (hitTest) {
            break; // прерывание проверки попадания
        }
    }
});

Неправильные границы игровых объектов

Чаще всего простейший и наиболее эффективный способ проверки ― это проверка попадания в прямоугольную область, однако во многих случаях этого недостаточно. Если игровой объект имеет неправильную форму, лучше проверять область, ограниченную треугольником или многоугольником. В таких случаях придется усложнить логику проверки попадания в обработчике событий игрового объекта. Как правило, соответствующая логика опирается на физику столкновений в игре.

В API Canvas есть интересная функция IsPointInPath(), способная выполнять проверку на наложение многоугольников. По существу, IsPointInPath(x, y) позволяет проверять, попадает ли данная точка (x, y) в произвольную форму (главным образом, многоугольный контур). Она возвращает значение true, если указанные координаты (x, y) находятся на текущем пути, определенном в контексте Canvas.

Применение функции isPointInPath()

Рисунок 6 иллюстрирует ситуацию, когда необходимо проверить координаты мыши на попадание в контур неправильной формы. В данном случае это простой треугольник.

Рисунок 6. Нажатие в пределах треугольного контура
Черный треугольник с указателем мыши в координатах 20,50 x, y

Закрашенный путь показан только для иллюстрации. Чтобы получить полезный результат IsPointInPath(), путь не нужно физически отображать на экране, поэтому достаточно определить его без всяких вызовов fill() или stroke(). Детали показаны в листинге 14.

Листинг 14. Использование функции isPointInPath для проверки попадания
$(canvas).on('handleClick', function(e, mouse) {

    // сначала определяем многоугольную область, ограничивающую путь
    context.save();
    context.beginPath();
    context.moveTo(0,0);
    context.lineTo(0,100);
    context.lineTo(100,100);
    context.closePath();
    
    // не нужно применять к пути fill() или stroke(), 
    // потому что он существует только для целей проверки попадания
    // context.fill();
    
    // выполняем проверку попадания внутрь нерегулярного контура
    // и определяем координаты мыши
    if (context.isPointInPath(mouse.x, mouse.y)) {
        // проверка прошла успешно, обработать событие click!
        
    }
    context.restore();
});

Чаще всего эффективнее писать алгоритмы столкновения самостоятельно, не используя IsPointInPath(), однако эта функция может служить хорошим инструментом для создания прототипов и быстрой разработки.


Совместимость с мобильными устройствами

Чтобы создать пример игры, совместимой с мобильными устройствами, нужно работать с событиями сенсорного экрана, а не мыши.

Хотя браузер мобильного устройства может интерпретировать касание пальца как событие click, как правило, полагаться только на прослушивание событий click мобильного браузера - не оптимальный подход. Чтобы гарантировать лучшее реагирование, нужно добавить прослушиватели специальных событий сенсорного экрана.

Обнаружение событий касания

Можно написать вспомогательную функцию, которая сначала определяет, поддерживает ли устройство события сенсорного экрана, а затем возвращает либо координаты мыши, либо координаты касания. Это позволяет вызывать функции, которые обрабатывают координаты ввода независимо от того, настольная это платформа или мобильная.

В листинге 15 приведен пример не зависящей от устройства функции ввода события мыши и касания с нормализованным ответом.

Листинг 15. Нормализация событий мыши и касания
function getPosition(e) {
    var position = {x: null, y: null};

    if (Modernizr.touch) { //глобальная переменная, обнаруживающая 
                                        //поддержку сенсорного экрана
        if (e.touches && e.touches.length > 0) {
            position.x = e.touches[0].pageX - canvasPosition.x;
            position.y = e.touches[0].pageY - canvasPosition.y;
        }
    }
    else {
        position.x = e.pageX - canvasPosition.x;
        position.y = e.pageY - canvasPosition.y;
    }

    return position;
}

Для обнаружения поддержки сенсорного экрана в примере используется библиотека Modernizr (см. раздел Ресурсы). Библиотека Modernizr обнаруживает поддержку сенсорного экрана, просто проверяя переменную Modernizr.touch, которая возвращает значение true, если устройство поддерживает события сенсорного экрана.

Обработчики событий, не зависящие от устройства

В процессе инициализации приложения предыдущий код определения прослушивателей событий можно заменить отдельными ветвями для устройств с сенсорным экраном и для мыши. Сопоставить события мыши с эквивалентными событиями касания достаточно легко. Например, mousedown заменяется на touchstart, а mouseup ― на touchend.

В листинге 16 приведен пример использования Modernizr для сопоставления эквивалентных событий мыши/сенсорного экрана. В нем также используется функция getPosition(), определенная в листинге 15.

Листинг 16. Использование нормализованных событий мыши/сенсорного экрана.
var eventName = Modernizr.touch ? 'touchstart' : 'click';

canvas.on(eventName, function(e) {
    e.preventDefault();

    var position = getPosition(e);
    //здесь происходит изменение положения мыши

    return false;
});

Если не нужно обрабатывать более сложные действия, такие как щипки и проведение пальцем по экрану, то этот подход обычно хорошо работает при прямом вводе событий мыши из настольного приложения. Предполагается система с одним касанием; если же необходимо обнаружение действий multi-touch, то потребуется дополнительный код (рассмотрение которого выходит за рамки этой статьи).


Заключение

В статье говорится о том, как обрабатывать события клавиатуры и мыши и как запретить нежелательное поведение браузера. Также обсуждаются стратегии вещания событий на игровые объекты и приводятся дополнительные соображения по проверке попадания и простой метод достижения совместимости с мобильными устройствами. Хотя тема ввода данных пользователем выходит далеко за рамки этой статьи, типичные сценарии пользовательского ввода могут служить отправной точкой при создании надежной, не зависящей от устройства библиотеки для обработки данных, вводимых пользователем в приложения HTML5.


Загрузка

ОписаниеИмяРазмер
Листинги программ для статьиarticle.listings.zip5 КБ

Ресурсы

Научиться

Получить продукты и технологии

  • jQuery: загрузите популярную библиотеку JavaScript, которая упрощает анализ HTML-документа, обработку событий, анимацию и Ajax-взаимодействия для ускорения Web-разработки.
  • Modernizr: библиотека JavaScript с открытым исходным кодом, которая помогает строить Web-сайты нового поколения на базе HTML5 и CSS3.
  • Kibo: популярная, простая библиотека JavaScript для обработки событий клавиатуры.

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы в первый раз заходите в developerWorks. Выберите данные в своем профиле (имя, страна/регион, компания) которые будут общедоступными и будут отображаться, когда вы публикуете какую-либо информацию. Вы можете изменить данные вашего ИБМ аккаунта в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Web-архитектура
ArticleID=851409
ArticleTitle=Обработка пользовательского ввода в играх с помощью технологии HTML5 Canvas
publish-date=12112012