Использование Gamepad API

HTML5 представил многие из необходимых компонентов для разработки многофункциональных интерактивных игр. Такие технологии, как , WebGL, и , наряду с реализациями JavaScript, имеют созрели до такой степени, что теперь они могут поддерживать многие задачи, ранее требовавшие нативного кода. Gamepad API — это способ для разработчиков и дизайнеров получать доступ и использовать геймпады и другие игровые контроллеры.

Gamepad API представляет новые события в объекте Window для чтения состояние геймпада и контроллера (далее геймпад ). В дополнение к этим событиям API также добавляет объект Gamepad , который можно использовать для запроса состояния подключенного геймпада, и navigator.getGamepads () , который можно использовать для получения списка геймпадов, известных странице.

Подключение к геймпаду

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

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

Вы можете использовать gamepadconnected следующим образом:

  window.addEventListener ("gamepadconnected", function (e) {console.log ("Геймпад подключен с индексом% d:% s.% d кнопок,% d осей.", e  .gamepad.index, напримерamepad.id, напримерamepad.buttons.length, напримерamepad.axes.length);});  

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

Отключение геймпада

Когда геймпад отключен, и если страница ранее получала данные для этого геймпада (например, gamepadconnected ), второе событие отправляется в окно с фокусом, gamepaddisconnected :

  window.addEventListener ("gamepaddisconnected", function (e) {console.log ("Геймпад отключен от индекса% d:% s", например, геймпад  .index, напримерamepad.id);});  

Свойство index геймпада будет уникальным для каждого устройства, подключенного к системе, даже если используется несколько контроллеров одного типа. Свойство index также функционирует как индекс в Array , возвращаемый Navigator.getGamepads () .

  var gamepads = {}; функция gamepadHandler (событие, подключение) {var gamepad = event.gamepad; //Примечание://геймпад === navigator.getGamepads () [gamepad.index] if (подключение) {gamepads [gamepad. индекс] = геймпад;  } else {удалить геймпады [gamepad.index];  }} window.addEventListener ("gamepadconnected", function (e) {gamepadHandler (e, true);}, false); window.addEventListener ("gamepaddisconnected", function (e) {gamepadHandler (e, false);}, false  );  

Этот предыдущий пример также демонстрирует, как свойство gamepad может удерживаться после завершения события — метод, который мы будем использовать для определения состояния устройства. запрос позже.

Запрос объекта геймпада

Как видите, геймпад События, описанные выше, включают свойство gamepad в объекте события, которое возвращает объект Gamepad . Мы можем использовать это, чтобы определить, какой геймпад (то есть его идентификатор) вызвал событие, поскольку несколько геймпадов могут быть подключены одновременно. С помощью объекта Gamepad мы можем сделать гораздо больше, в том числе удерживать ссылку на него и запрашивать его, чтобы узнать, какие кнопки и оси были нажаты в любой момент. Это часто желательно для игр или других интерактивных веб-страниц, которым необходимо знать состояние геймпада сейчас и при следующем срабатывании события.

Выполнение таких проверок, как правило, требует использования Gamepad в сочетании с циклом анимации (например, requestAnimationFrame ), где разработчики хотят принимать решения для текущего кадра на основе состояния геймпада или геймпадов.

Метод Navigator.getGamepads () возвращает массив всех устройств, которые в настоящее время видны на веб-странице, в виде объектов Gamepad ( первое значение всегда null , поэтому null будет возвращено, если нет подключенных геймпадов.) Затем это можно использовать для получения той же информации. Например, первый пример кода, приведенный выше, вы должны переписать, как показано ниже:

  window.addEventListener ("gamepadconnected", function (e) {var gp = navigator.getGamepads ()  [egamepad.index]; console.log ("Геймпад подключен с индексом% d:% s.% d кнопок,% d осей.", gp.index, gp.id, gp.buttons.length, gp.axes  .length);});  

Свойства объекта Gamepad следующие:

  • id : строка, содержащая некоторую информацию о контроллере. Это не указано строго, но в Firefox он будет содержать три части информации, разделенные дефисом ( - ): две четырехзначные шестнадцатеричные строки, содержащие поставщика USB и идентификатор продукта контроллера, и имя контроллера, предоставленное драйвером. Эта информация предназначена для того, чтобы вы могли найти сопоставление для элементов управления на устройстве, а также отобразить полезную обратную связь для пользователя.
  • index : целое число, которое уникален для каждого геймпада, подключенного к системе в данный момент. Это можно использовать для различения нескольких контроллеров. Обратите внимание, что отключение устройства и последующее подключение нового устройства может повторно использовать предыдущий индекс..
  • сопоставление : строка, указывающая, переназначил ли браузер элементы управления на устройстве в известную компоновку. В настоящее время поддерживается только одна известная раскладка — стандартный геймпад. Если браузер может сопоставить элементы управления на устройстве с этим макетом, свойство mapping будет установлено в строку standard .
  • connected : логическое значение, указывающее, подключен ли геймпад к системе. Если это так, значение равно True ; в противном случае это False .
  • buttons : массив объектов GamepadButton представляющие кнопки, присутствующие на устройстве. У каждой кнопки GamepadButton есть нажатие и свойство value :
    • loaded — это логическое значение, указывающее, нажата ли кнопка в данный момент ( true ) или не нажата ( false ).
    • Свойство value — это значение с плавающей запятой, используемое для включения представления аналоговых кнопок, таких как триггеры на многих современных геймпадах. Значения нормализованы до диапазона 0,0..1,0, где 0,0 представляет кнопку, которая не нажата, а 1,0 представляет кнопку, которая полностью нажата.
  • axes : массив, представляющий элементы управления с осями, присутствующими на устройстве (например, аналоговые джойстики). Каждая запись в массиве представляет собой значение с плавающей запятой в диапазоне от -1,0 до 1,0, представляющее положение оси от наименьшего значения (-1,0) до наибольшего значения (1.0).
  • timestamp : возвращает DOMHighResTimeStamp , представляющий последний раз, когда данные для этого геймпада были обновлены, что позволяет разработчикам определить, были ли оси и Данные кнопки были обновлены с оборудования. Значение должно быть относительно атрибута navigationStart интерфейса PerformanceTiming . Значения монотонно увеличиваются, что означает, что их можно сравнивать для определения порядка обновлений, поскольку новые значения всегда будут больше или равны старым значениям. Обратите внимание, что это свойство в настоящее время не поддерживается в Firefox.

Примечание : объект Gamepad доступен в gamepadconnected , а не сам объект Window из соображений безопасности. Получив ссылку на него, мы можем запросить его свойства для получения информации о текущем состоянии геймпада. Незаметно для себя этот объект будет обновляться каждый раз при изменении состояния геймпада.

Использование информации о кнопках

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

Для начала мы объявляем некоторые переменные: абзац gamepadInfo , в котором содержится информация о подключении. записанный в мяч , который мы хотим переместить, переменную start , которая действует как идентификатор для requestAnimation Frame , переменные a и b , которые действуют как модификаторы положения для перемещения мяча, и сокращенные переменные, которые будут использоваться для requestAnimationFrame ( ) и cancelAnimationFrame () кроссбраузерные вилки.

  var gamepadInfo = document.getElementById ("gamepad-info");  var ball = document.getElementById ("ball"); var start; var a = 0; var b = 0;  

Затем мы используем подключенный геймпад event для проверки подключения геймпада. Когда он подключен, мы захватываем геймпад с помощью Navigator.getGamepads () [0] , выводим информацию о геймпаде в нашу информацию о геймпаде div и запускает функцию gameLoop () , которая запускает весь процесс движения мяча.

  window.addEventListener (  "gamepadconnected", функция (e) {var gp = navigator.getGamepads () [egamepad.index]; gamepadInfo.innerHTML = "Геймпад подключен по индексу" + gp.index + ":" + gp.id + ".  Он имеет кнопки "+ gp.buttons.length +" и "+ gp.axes.length +" axes. "; GameLoop ();});  

Теперь мы используем gamepaddisconnected , чтобы проверить, отключен ли геймпад снова. Если это так, мы останавливаем цикл requestAnimationFrame () (см. Ниже) и возвращаем информацию геймпада к исходной.

  окно  .addEventListener ("gamepaddisconnected", function (e) {gamepadInfo.innerHTML = "Waiting for gamepad."; cancelRequestAnimationFrame (start);});  

Здесь Chrome работает по-другому. Вместо того, чтобы постоянно сохранять последнее состояние геймпада в переменной, он хранит только моментальный снимок, поэтому, чтобы сделать то же самое в Chrome, вы должны продолжать его опрос, а затем использовать объект Gamepad в коде только тогда, когда это доступно. Мы сделали это ниже, используя Window.setInterval () ; как только объект становится доступным, выводится информация о геймпаде, запускается игровой цикл и интервал очищается с помощью Window.clearInterval () . Обратите внимание, что в более старых версиях Chrome Navigator.getGamepads () реализован с префиксом webkit . Мы пытаемся обнаружить и обработать как версию с префиксом, так и стандартную версию функции для обратной совместимости.

  var interval; if (! ('Ongamepadconnected' in window)) { //Нет доступных событий геймпада, вместо этого опрос.  interval = setInterval (pollGamepads, 500);} function pollGamepads () {var gamepads = navigator.getGamepads?  штурман. getGamepads (): (navigator.webkitGetGamepads? navigator.webkitGetGamepads: []);  for (var i = 0; i  

Теперь перейдем к основному циклу игры. При каждом выполнении цикла мы проверяем, нажата ли одна из четырех кнопок; если это так, мы соответствующим образом обновляем значения переменных перемещения a и b , а затем обновляем left и top , изменяя их значения на текущие значения a и b соответственно. Это дает эффект перемещения мяча по экрану. В текущих версиях Chrome (версия 34 на момент написания этой статьи) значения кнопок хранятся в виде массива двойных значений, а не объектов GamepadButton . Это исправлено в разрабатываемых версиях.

После того, как все это будет сделано, мы используем наш requestAnimationFrame () для запроса следующего кадра анимации, выполняя gameLoop () снова.

  function buttonPressed (b) {if (typeof (b) == "object") {return b.pressed;  } return b == 1.0;} function gameLoop () {var gamepads = navigator.getGamepads?  Navigator.getGamepads (): (navigator.webkitGetGamepads? navigator.webkitGetGamepads: []);  если (! геймпады) {возврат;  } var gp = gamepads [0];  если (buttonPressed (gp.buttons [0])) {b--;  } иначе, если (buttonPressed (gp.buttons [2])) {b ++;  } если (buttonPressed (gp.buttons [1])) {a ++;  } else if (buttonPressed (gp.buttons [3])) {a--;  } ball.style.left = a * 2 + "px";  ball.style.top = b * 2 + «пикс»;  start = requestAnimationFrame (gameLoop);}  

Полный пример: отображение состояния геймпада

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

  var haveEvents = 'ongamepadconnected' в окне; var controllers = {}; function connecthandler (e)  {addgamepad (например, геймпад);} функция addgamepad (геймпад) {контроллеры [gamepad.index] = геймпад;  var d = document.createElement ("div");  d.setAttribute («идентификатор», «контроллер» + gamepad.index);  var t = document.createElement ("h1");  t.appendChild (document.createTextNode ("геймпад:" + gamepad.id));  d.appendChild (t);  var b = document.createElement ("div");  b.className = "кнопки";  для (var я = 0; я  

Технические характеристики

Технические характеристики Статус Комментарий
Геймпад
Определение ‘ Gamepad »в этой спецификации.
Рабочий черновик Первоначальное определение

Совместимость с браузером

Таблицы BCD загружаются только в браузере

Таблица совместимости на этой странице генерируется из структурированных данных. Если вы хотите внести свой вклад в данные, посетите https://github.. com/mdn/browser-compat-data и отправьте нам запрос на перенос.

Оцените статью
Botgadget.ru
Добавить комментарий