Статьи

Создайте кросс-браузерный сенсорный джойстик с Hand.js

В настоящее время я работаю над несколькими игровыми проектами для современных браузеров и проектов Магазина Windows 8. Некоторые из них используют HTML5 в качестве основы для упрощения таргетинга на несколько устройств. Затем я искал унифицированный способ решения всех задач на всех платформах: Windows 8 / RT, Windows Phone 8, iPad, Android и FirefoxOS.

Как вы, возможно, уже обнаружили в моей предыдущей статье « Объединение касания и мыши» — как Pointer Events упростит поддержку касаний в разных браузерах , IE10 в Windows 8 / RT и Windows Phone 8 реализует модель событий указателя, которую мы представили в W3C. Чтобы унифицированно рассмотреть эту модель событий указателя и модель, реализованную в браузерах на основе WebKit, мы собираемся использовать библиотеку Дэвида Катухе HandJS. Прочтите пост его блога здесь: HandJS — полизаполнение для поддержки событий указателя в каждом браузере . Эта идея нацелена на модель Pointer, и библиотека будет распространять сенсорные события на все особенности платформы.

После того, как у меня были все технические детали, я искал отличный способ внедрить виртуальный сенсорный джойстик в мою игру. Я не большой поклонник клавиш со стрелками, которые нужно трогать. С другой стороны, виртуальные аналоговые панели часто не очень хорошо расположены. Но я наконец-то обнаружил, что Себ Ли-Делисл уже переварил это и создал эту удивительную концепцию, описанную в игровом контроллере Multi-touch в JavaScript / HTML5 для iPad . Код доступен на GitHub здесь: JSTouchController

Идея заключалась в том, чтобы взять его код и провести рефакторинг сенсорной части для нацеливания на модель Pointer вместо оригинального подхода WebKit Touch. Работая над этим несколько месяцев назад, я обнаружил, что Борис Смус из Google уже начал более или менее делать это. Это было сделано в то время, когда он работал над своей собственной библиотекой Pointer.js, как описано в его статье « Обобщенный ввод в сети с несколькими устройствами» Однако в то время Борис копировал старую версию реализации событий указателя IE10, а его библиотека не работала в IE10. Вот почему, даже если работа Бориса была потрясающей, мы решили поработать над собственной версией. Действительно, библиотека Дэвида в настоящее время ориентирована на последнюю и самую последнюю версию W3C, которая в настоящее время находится в черновике последнего вызова . Если вы посмотрите на обе библиотеки, то увидите, что HandJS использует несколько разных подходов в нескольких частях кода. Затем мы будем использовать HandJS в этой статье для создания нашего сенсорного джойстика.

Пример 1: трекер указателей

Этот пример помогает вам отслеживать различные входные данные на экране. Он отслеживает и следит за различными пальцами, нажимающими элемент canvas Он основан на примере Seb, доступном на GitHub здесь: Touches.html

Благодаря Hand.js мы сделаем его совместимым для всех браузеров. Он также будет отслеживать стилус и / или мышь в зависимости от типа оборудования, которое вы сейчас тестируете!

Вот HTML5-видео о результате в IE10, работающем под Windows 8. Вы увидите несколько голубых кругов, следящих за пальцами, затем красный круг, отслеживающий мышь, и зеленый круг, отслеживающий перо:

Скачать видео: MP4 , WebM , HTML5 видеоплеер от VideoJS

Та же веб-страница обеспечивает тот же результат в Chrome на Windows 8 или на устройствах iOS / Android / FirefoxOS (за исключением того, что перо поддерживается только IE10). Благодаря HandJS, напишите его один раз, и он будет работать везде! Sourire

Вы видели в видео, что голубые указатели имеют тип «TOUCH», а красный — «MOUSE». Если у вас сенсорный экран, вы можете получить тот же результат, протестировав эту страницу, встроенную в этот iframe:

Этот пример отлично работает на сенсорном устройстве Windows 8 / RT, Windows Phone 8, iPad / iPhone или Android / FirefoxOS! Если у вас нет сенсорного устройства, HandJS автоматически переключится на мышь. После этого вы сможете отслеживать по крайней мере 1 указатель с помощью мыши.

Посмотрим, как получить этот результат единым способом. Весь код живет в Touches.js :

  «использовать строгое» ;

 // подкладка слоя с откатом setTimeout 
  window.requestAnimFrame = ( function () {
     вернуть window.requestAnimationFrame ||
     window.webkitRequestAnimationFrame ||
     window.mozRequestAnimationFrame ||
     window.oRequestAnimationFrame ||
     window.msRequestAnimationFrame ||
     function (callback) {
         window.setTimeout (обратный вызов, 1000/60);
     };
 }) ();

 указатели вар ;  // коллекции указателей 

  вар холст,
 с;  // c - это контекст холста 2D 

  document.addEventListener ( "DOMContentLoaded" , init);

 window.onorientationchange = resetCanvas;
 window.onresize = resetCanvas;

 функция init () {
     setupCanvas ();
     указатели = новая коллекция ();
     canvas.addEventListener ( 'pointerdown' , onPointerDown, false );
     canvas.addEventListener ( 'pointermove' , onPointerMove, false );
     canvas.addEventListener ( 'pointerup' , onPointerUp, false );
     canvas.addEventListener ( 'pointerout' , onPointerUp, false );
     requestAnimFrame (нарисовать);
 }

 функция resetCanvas (e) {
     // изменить размер холста - но помните - это также очищает холст. 
      canvas.width = window.innerWidth;
     canvas.height = window.innerHeight;

     // убедитесь, что мы прокручиваем вверх слева. 
      window.scrollTo (0, 0);
 }

 function draw () {
     c.clearRect (0, 0, canvas.width, canvas.height);

     pointers.forEach ( function (pointer) {
         c.beginPath ();
         c.fillStyle = "white" ;
         c.fillText (pointer.type + "id:" + pointer.identifier + "x:"
           + pointer.x + "y:" + pointer.y, pointer.x + 30, pointer.y - 30);

         c.beginPath ();
         c.strokeStyle = pointer.color;
         c.lineWidth = "6" ;
         c.arc (pointer.x, pointer.y, 40, 0, Math.PI * 2, true );
         c.stroke ();
     });

     requestAnimFrame (нарисовать);
 }

 функция createPointerObject (event) {
     тип вар ;
     вар цвет;
     switch (event.pointerType) {
         case case.POINTER_TYPE_MOUSE:
             type = "MOUSE" ;
             цвет = "красный" ;
             перерыв ;
         case case.POINTER_TYPE_PEN:
             type = "PEN" ;
             цвет = "лайм" ;
             перерыв ;
         case case.POINTER_TYPE_TOUCH:
             type = "TOUCH" ;
             цвет = "голубой" ;
             перерыв ;
     }
     return {identifier: event.pointerId, x: event.clientX, y: event.clientY, 
     тип: тип, цвет: цвет};
 }

 function onPointerDown (e) {
     pointers.add (e.pointerId, createPointerObject (e));
 }

 function onPointerMove (e) {
     if (pointers.item (e.pointerId)) {
         pointers.item (e.pointerId) .x = e.clientX;
         pointers.item (e.pointerId) .y = e.clientY;
     }
 }

 function onPointerUp (e) {
     pointers.remove (e.pointerId);
 }

 function setupCanvas () {
     canvas = document.getElementById ( 'canvasSurface' );
     c = canvas.getContext ( '2d' );
     canvas.width = window.innerWidth;
     canvas.height = window.innerHeight;
     c.strokeStyle = "#ffffff" ;
     c.lineWidth = 2;
 } 

Ну, я думаю, что код довольно прост. Я регистрируюсь на событие pointerdown / move / up, как описано в моей вводной статье о событиях MSPointer . В обработчике указателя вниз я ловлю идентификатор, координаты X & Y и тип указателей (сенсорный, перо или мышь) внутри объекта, сгенерированного на лету, помещенного в объект коллекции указателей . Эта коллекция индексируется идентификатором указателей. Объект коллекции описан в Collection.js . Затем функция draw () перечисляет эту коллекцию, чтобы нарисовать несколько голубых / красных / салатовых кругов в зависимости от типа в точном месте, где вы касаетесь экрана. Он также добавляет текст на каждой стороне круга для отображения деталей указателя. Обработчик pointermove обновляет координаты связанного указателя в коллекции, а pointerup / out просто удаляет его из коллекции. Hand.JS делает этот код совместимым для IE10, передавая указатель / перемещение / вверх / наружу к связанным событиям MSPointerDown / Move / Up / Out и событиям touchstart / move / end для браузеров WebKit.

Если вы хотите, вы можете просмотреть полный исходный код здесь: http://david.blob.core.windows.net/html5/touchjoystick/Touches.html

Пример 2: Контроллер видеоигры с простой космической игрой

Давайте теперь посмотрим на пример, который меня больше всего заинтересовал. Вы, вероятно, также захотите, если вы ищете виртуальную аналоговую сенсорную панель для ваших игр HTML5. Идея состоит в том, чтобы коснуться в любом месте на левой стороне экрана. В точном месте, где вы будете касаться экрана, он покажет простой, но очень эффективный пэд. Перемещение пальца обновит виртуальную сенсорную панель и переместит простой космический корабль. Если дотронуться до правой стороны экрана, на экране появятся красные кружки, и эти кружки сгенерируют пули, выходящие из космического корабля. Еще раз, это основано на примере Seb, доступном на GitHub здесь: TouchControl.html

Вот видео обновленного примера результата в IE10 под Windows 8: