[Gamepad API] JS를 통해 Logical 게임 패드의 조작 이벤트 가져오기

21991 단어 JavaScripttech

개요


Loogicool 게임 패드를 샀기 때문에 컨트롤러로 조작할 수 있는 웹 페이지를 만들고 싶어요
JavaScript를 사용하여 버튼 이벤트를 가져오는 방법을 의사록으로 요약합니다.

작업 환경

  • Mac(브라우저: Google Chrome)
  • Logiicool 게임 패드https://www.amazon.co.jp/dp/B00CDG799E
  • Mac로 Logical 이동


    Loogicool은 윈도를 위한 게임 매트리스지만 운전자 맥을 넣으면 동작한다.
    ↓ 기사를 넣는 방법은 여기를 참고하세요.
    https://www.noname774.xyz/entry/2020/11/01/161703
    드라이버를 정상적으로 설치할 수 있다면 시스템 환경 설정에 게임 패드 메뉴가 표시됩니다.

    켜면 이런 느낌으로 게임 매트의 동작 테스트 등을 할 수 있다.
    게임 패드의 버튼을 적당히 누르면 이 화면에서 시뮬레이션을 하면 맥에 정상적으로 연결될 수 있다.

    연결 이벤트


    버튼을 누르는 이벤트를 얻기 전에, 게임 패드가 연결되었는지 확인해야 합니다.
    게임패드 connected 이벤트를 이용해서 얻으려고 합니다.
    window.addEventListener("gamepadconnected", (e) => {
      console.log(
        "Gamepad connected at index %d: %s. %d buttons, %d axes.",
        e.gamepad.index,
        e.gamepad.id,
        e.gamepad.buttons.length,
        e.gamepad.axes.length
      );
    });
    
    연결을 확인하면 콘솔에 이렇게 표시됩니다.
    Gamepad connected at index 0: Xbox 360 Wired Controller (Vendor: 046d Product: c21d). 15 buttons, 6 axes.
    
    연결을 확인한 후 버튼 수령 등을 진행한다.

    버튼 가져오기


    버튼 누르기에 관해서는 특별한 준비 활동requestAnimationFrame이 없는 것 같아서 매번 프레임을 확인하는 방법으로 이루어진다.
    참조
    const buttonPressed = (button) => {
      if (typeof button == "object") {
        return button.pressed;
      }
      return button == 1.0;
    };
    
    const gameLoop = () => {
      const gamepads = navigator.getGamepads
        ? navigator.getGamepads()
        : navigator.webkitGetGamepads
        ? navigator.webkitGetGamepads
        : [];
      if (!gamepads) {
        return;
      }
    
      const gp = gamepads[0];
      if (buttonPressed(gp.buttons[0])) {
        console.log("Aボタン押下")
      };
    
      requestAnimationFrame(gameLoop);
    };
    
    MDN 문서.
    A버튼을 간단히 누르면 콘솔에 정보가 표시됩니다.
    (이 gameLoop 함수는 아까 window.addEventListener("gamepadconnected", ... 중칭)

    버튼 대응 테이블


    버튼은 gamepads.buttons, 아날로그봉(다음 장)은 gamepads.axes으로 각각의 Arry를 획득할 수 있다.
    Gamepad API 설명서에 XBox360 공식 게임 패드의 버튼 레이아웃이 실렸다.
    buttons: [
    'DPad-Up','DPad-Down','DPad-Left','DPad-Right',
    'Start','Back','Axis-Left','Axis-Right',
    'LB','RB','Power','A','B','X','Y',
    ],
    다만, 이번에 사용한 로지컬은 게임 매트가 달라 다음과 같이 정리했다.(다른 게임 매트는 다를 수 있으니 주의하세요.)
    해봤는데 왼쪽에 있는 아날로그봉은 버튼이고 봉 모양의 한쪽에 십자키가 들어갔는데... 이 근처는 저렴한 비공식 게임 매트리스라서 어쩔 수 없어요.
    로그인 버튼
    배열 번호
    A
    0
    B
    1
    X
    2
    Y
    3
    LB
    4
    RB
    5
    왼방망이로 밀어넣다
    6
    오른손으로 밀어넣다
    7
    START
    8
    BACK
    9
    중앙 Logical 버튼
    10
    왼쪽 몽둥이 위
    11
    왼쪽 몽둥이 아래
    12
    좌익수
    13
    좌익우
    14

    스틱 입력 가져오기


    boolean을 되돌려주는 단추에 대해 봉(LT, RT 포함)은 -1~1의 값을 되돌려줍니다.
    Loogicool 스틱
    배열 번호

    십자 키 왼쪽
    0
    -1
    십자 키 오른쪽
    0
    1
    십자 키 위
    1
    -1
    십자 키 아래
    1
    1
    LT
    2
    1
    오른쪽
    3
    -1
    우익수
    3
    1
    오른쪽 몽둥이 위
    4
    -1
    오른손
    4
    1
    RT
    5
    1

    운영 프레젠테이션


    이번에는 버튼의 입력을 얻어 이미지 이동을 보여 줍니다.
    <head>
      <style>
        body {
          margin: 0;
          background: black;
        }
        .kuma {
          position: fixed;
          top: calc(50% - 50px);
          left: calc(50% - 50px);
          width: 100px;
          height: 100px;
        }
      </style>
    </head>
    <body>
      <img id="kuma" class="kuma" src="kuma.gif" />
      <script>
        const kuma = document.getElementById("kuma");
        let start;
        let a = 0;
        let b = 0;
    
        const buttonPressed = (button) => {
          if (typeof button == "object") {
            return button.pressed;
          }
          return button == 1.0;
        };
    
        const gameLoop = () => {
          const gamepads = navigator.getGamepads
            ? navigator.getGamepads()
            : navigator.webkitGetGamepads
            ? navigator.webkitGetGamepads
            : [];
          if (!gamepads) {
            return;
          }
      
          const gp = gamepads[0];
          if (buttonPressed(gp.buttons[3])) {
            b--;
          } else if (buttonPressed(gp.buttons[0])) {
            b++;
          }
          if (buttonPressed(gp.buttons[1])) {
            a++;
          } else if (buttonPressed(gp.buttons[2])) {
            a--;
          }
    
          const kumaLeft = kuma.getBoundingClientRect().left;
          const kumaTop = kuma.getBoundingClientRect().top;
          const speed = 5;
    
          kuma.style.left = kumaLeft + a * speed + "px";
          kuma.style.top = kumaTop + b * speed + "px";
          a = 0;
          b = 0;
    
          start = requestAnimationFrame(gameLoop);
        };
    
        window.addEventListener("gamepadconnected", (e) => {
          gameLoop();
        });
      </script>
    </body>
    

    나는 순조롭게 운행했다.

    참고 자료


    https://developer.mozilla.org/ja/docs/Web/API/Gamepad_API/Using_the_Gamepad_API
    https://developer.mozilla.org/ja/docs/Games/Techniques/Controls_Gamepad_API

    좋은 웹페이지 즐겨찾기