게임패드로 Chrome 공룡 게임을 플레이하세요.

Gamepad API를 사용하여 웹 게임을 한 단계 업그레이드하는 방법을 알아보세요.

Chrome의 오프라인 페이지 이스터 에그는 역사상 최악의 비밀 중 하나입니다 ([citation needed], 그러나 극적인 효과에 대한 주장). Space 키를 누르거나 휴대기기에서는 공룡을 탭하면 오프라인 페이지가 플레이 가능한 아케이드 게임이 됩니다. 여러분도 아시겠지만 게임을 하고 싶을 때 오프라인으로 전환할 필요가 없습니다. Chrome에서는 about://dino을(를) 방문하고, 괴짜라면 about://network-error/-106을(를) 찾아보세요. 알고 계셨나요? 인코더-디코더 모델이 매달 2억 7천만 개의 Chrome 공룡 게임이 플레이되는 횟수

<ph type="x-smartling-placeholder">
</ph> Chrome 공룡 게임을 보여주는 Chrome 오프라인 페이지입니다. <ph type="x-smartling-placeholder">
</ph> 스페이스 키를 눌러 플레이하세요!

아마 알아두면 더욱 유용하고 잘 모르는 또 다른 사실은 게임패드로 게임을 플레이할 수 있는 아케이드 모드입니다. 게임패드 지원은 약 1년 전에 이 문서 작성 시점을 기준으로 커밋: 라일리 그랜트 보시다시피 이 게임은 Chromium 프로젝트, 완전히 완료되었습니다. 오픈소스입니다. 포함 Gamepad API를 사용하는 방법을 보여드리겠습니다.

Gamepad API 사용

기능 감지 및 브라우저 지원

Gamepad API는 두 환경에서 보편적으로 뛰어난 브라우저 지원을 제공합니다. 있습니다. 다음 스니펫을 사용하여 Gamepad API가 지원되는지 확인할 수 있습니다.

if ('getGamepads' in navigator) {
  // The API is supported!
}

브라우저가 게임패드를 나타내는 방식

브라우저가 게임패드를 Gamepad로 나타냅니다. 객체입니다. Gamepad에는 다음과 같은 속성이 있습니다.

  • id: 게임패드의 식별 문자열입니다. 이 문자열은 해당 브랜드의 브랜드 또는 스타일을 나타냅니다. 게임패드 기기에 연결할 수 있습니다.
  • displayId: VRDisplay.displayId/ 연결된 VRDisplay입니다 (관련 있는 경우).
  • index: 탐색기의 게임패드 색인입니다.
  • connected: 게임패드가 아직 시스템에 연결되어 있는지 여부를 나타냅니다.
  • hand: 컨트롤러를 쥐고 있거나 잡을 가능성이 가장 높은 손을 정의하는 열거형입니다. 인치
  • timestamp: 이 게임패드의 데이터가 마지막으로 업데이트된 시간입니다.
  • mapping: 이 기기에서 사용 중인 버튼 및 축 매핑("standard" 또는 "xr-standard"입니다.
  • pose: GamepadPose 객체 WebVR 컨트롤러와 관련된 포즈 정보를 나타냅니다.
  • axes: 게임패드의 모든 축에 대한 값의 배열로, 다음과 같이 선형으로 정규화됩니다. -1.0~1.0
  • buttons: 게임패드의 모든 버튼에 관한 버튼 상태의 배열입니다.

버튼은 디지털 (눌리거나 누르지 않음) 또는 아날로그 (예: 78% 누름)일 수 있습니다. 이 이러한 이유로 버튼은 다음 속성과 함께 GamepadButton 객체로 보고됩니다.

  • pressed: 버튼을 누른 상태 (버튼을 누르는 경우true, 버튼을 false 버튼을 누릅니다.
  • touched: 버튼의 터치 상태입니다. 버튼이 터치를 감지할 수 있는 경우 속성은 버튼을 터치하면 true이고 터치하지 않으면 false입니다.
  • value: 아날로그 센서가 있는 버튼의 경우 이 속성은 버튼이 눌렸습니다. 0.0~1.0 범위로 선형 정규화되었습니다.
  • hapticActuators: 다음이 포함된 배열 GamepadHapticActuator 객체입니다. 각 객체는 컨트롤러에서 사용할 수 있는 햅틱 반응 하드웨어를 나타냅니다.

브라우저와 게임패드에 따라 발생할 수 있는 또 다른 문제는 vibrationActuator 속성입니다. 두 가지 종류의 럼블 효과를 허용합니다.

  • 이중 럼블: 게임패드의 각 그립에 하나씩 총 두 개의 편심 회전 매스 액추에이터로 생성되는 햅틱 반응 효과입니다.
  • 트리거-럼블: 두 개의 독립 모터에 의해 생성되는 햅틱 반응 효과로, 게임패드의 트리거 각각에 모터가 하나씩 있습니다.

다음 도식 개요는 사양에서 바로 일반 게임패드의 버튼과 축의 매핑과 배열을 보여줍니다.

<ph type="x-smartling-placeholder">
</ph> 일반 게임패드의 버튼 및 축 매핑에 대한 도식 개요 <ph type="x-smartling-placeholder">
</ph> 표준 게임패드 레이아웃의 시각적 표현 (출처).

게임패드 연결 시 알림

게임패드가 연결된 시점을 알아보려면 다음에서 트리거되는 gamepadconnected 이벤트를 수신 대기합니다. window 객체. 사용자가 USB 또는 블루투스를 사용하여 게임패드를 연결하면 적절한 이름의 gamepad 속성에 게임패드의 세부정보가 있는 GamepadEvent가 실행됩니다. 다음에서 제가 누워 있던 Xbox 360 컨트롤러의 예를 레트로 게임).

window.addEventListener('gamepadconnected', (event) => {
  console.log(' 🎮 A gamepad was connected:', event.gamepad);
  /*
    gamepad: Gamepad
    axes: (4) [0, 0, 0, 0]
    buttons: (17) [GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton]
    connected: true
    id: "Xbox 360 Controller (STANDARD GAMEPAD Vendor: 045e Product: 028e)"
    index: 0
    mapping: "standard"
    timestamp: 6563054.284999998
    vibrationActuator: GamepadHapticActuator {type: "dual-rumble"}
  */
});

게임패드 연결이 해제되었을 때 알림

게임패드 연결 끊김 알림을 받는 것은 연결이 감지되는 방식과 유사하게 발생합니다. 이번에는 앱이 gamepaddisconnected 이벤트를 수신 대기합니다. 다음 예에서 Xbox 360 컨트롤러를 분리하면 connected이(가) false 상태가 됩니다.

window.addEventListener('gamepaddisconnected', (event) => {
  console.log('❌ 🎮 A gamepad was disconnected:', event.gamepad);
  /*
    gamepad: Gamepad
    axes: (4) [0, 0, 0, 0]
    buttons: (17) [GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton, GamepadButton]
    connected: false
    id: "Xbox 360 Controller (STANDARD GAMEPAD Vendor: 045e Product: 028e)"
    index: 0
    mapping: "standard"
    timestamp: 6563054.284999998
    vibrationActuator: null
  */
});

게임 루프의 게임패드

게임패드를 점유하려면 배열을 반환하는 navigator.getGamepads() 호출로 시작합니다. Gamepad개 항목 포함 Chrome의 배열은 항상 4개 항목으로 길이가 고정되어 있습니다. 0 이하인 경우 4개의 게임패드가 연결된 경우 항목은 그냥 null일 수 있습니다. 항상 모든 항목을 확인하시기 바랍니다. 게임패드가 '기억'하고 항상 게재될 수 있는 것은 아니며 있습니다.

// When no gamepads are connected:
navigator.getGamepads();
// (4) [null, null, null, null]

하나 이상의 게임패드가 연결되어 있지만 navigator.getGamepads()에서 여전히 항목 null개를 보고하는 경우 CANNOT TRANSLATE 각 게임패드의 버튼을 누르면 됩니다. 그런 다음 게임패드를 폴링할 수 있습니다. 상태를 게임 루프에 추가해야 합니다.

const pollGamepads = () => {
  // Always call `navigator.getGamepads()` inside of
  // the game loop, not outside.
  const gamepads = navigator.getGamepads();
  for (const gamepad of gamepads) {
    // Disregard empty slots.
    if (!gamepad) {
      continue;
    }
    // Process the gamepad state.
    console.log(gamepad);
  }
  // Call yourself upon the next animation frame.
  // (Typically this happens every 60 times per second.)
  window.requestAnimationFrame(pollGamepads);
};
// Kick off the initial game loop iteration.
pollGamepads();
드림

진동 액추에이터

vibrationActuator 속성은GamepadHapticActuator 햅틱을 위해 힘을 가할 수 있는 모터 또는 기타 액추에이터의 구성 의견을 보냅니다. 햅틱 효과는 Gamepad.vibrationActuator.playEffect()를 호출하여 재생할 수 있습니다. 유일한 유효한 효과 유형은 'dual-rumble''trigger-rumble'입니다.

지원되는 럼블 효과

if (gamepad.vibrationActuator.effects.includes('trigger-rumble')) {
  // Trigger rumble supported.
} else if (gamepad.vibrationActuator.effects.includes('dual-rumble')) {
  // Dual rumble supported.
} else {
  // Rumble effects aren't supported.
}

듀얼 럼블

듀얼 럼블은 편심 회전하는 질량 진동 모터가 있습니다. 이 구성에서 모터 중 하나가 전체 게임패드를 진동할 수 있습니다. 두 질량은 동일하지 않으므로 각각의 효과를 결합하여 더 복잡한 햅틱 효과를 만들 수 있습니다. 이중 럼블 효과는 4개의 매개변수로 정의됩니다.

  • duration: 진동 효과 지속 시간을 밀리초 단위로 설정합니다.
  • startDelay: 진동이 시작될 때까지의 지연 시간을 설정합니다.
  • strongMagnitudeweakMagnitude: 과체중의 진동 강도 수준을 설정합니다. 0.0~1.0 범위로 정규화된 더 가벼운 편심 회전 질량 모터
// This assumes a `Gamepad` as the value of the `gamepad` variable.
const dualRumble = (gamepad, delay = 0, duration = 100, weak = 1.0, strong = 1.0) => {
  if (!('vibrationActuator' in gamepad)) {
    return;
  }
  gamepad.vibrationActuator.playEffect('dual-rumble', {
    // Start delay in ms.
    startDelay: delay,
    // Duration in ms.
    duration: duration,
    // The magnitude of the weak actuator (between 0 and 1).
    weakMagnitude: weak,
    // The magnitude of the strong actuator (between 0 and 1).
    strongMagnitude: strong,
  });
};

울음소리 트리거

트리거 럼블은 두 개의 독립 모터에 의해 생성되는 햅틱 반응 효과로, 게임패드의 트리거 각각에 모터 하나가 있습니다.

// This assumes a `Gamepad` as the value of the `gamepad` variable.
const triggerRumble = (gamepad, delay = 0, duration = 100, weak = 1.0, strong = 1.0) => {
  if (!('vibrationActuator' in gamepad)) {
    return;
  }
  // Feature detection.
  if (!('effects' in gamepad.vibrationActuator) || !gamepad.vibrationActuator.effects.includes('trigger-rumble')) {
    return;
  }
  gamepad.vibrationActuator.playEffect('trigger-rumble', {
    // Duration in ms.
    duration: duration,
    // The left trigger (between 0 and 1).
    leftTrigger: leftTrigger,
    // The right trigger (between 0 and 1).
    rightTrigger: rightTrigger,
  });
};

권한 정책과의 통합

게임패드 API 사양은 정책 제어 기능 문자열 "gamepad"입니다. 기본 allowlist"self"입니다. 문서의 권한 정책에 따라 navigator.getGamepads() 액세스 허용 여부를 지정합니다. 다음에서 사용 중지된 경우 문서에 있는 내용에 관계없이 navigator.getGamepads() gamepadconnectedgamepaddisconnected 이벤트가 실행됩니다.

<iframe src="index.html" allow="gamepad"></iframe>

데모

다음 예에는 게임패드 테스터 데모가 삽입되어 있습니다. 소스 코드 Glitch에서 사용할 수 있습니다. 다음을 연결하여 데모를 사용해 보세요. 게임패드의 축을 움직이거나 버튼을 눌러 조작할 수 있습니다.

보너스: web.dev에서 Chrome 공룡 게임을 플레이하세요

이 기기에서 게임패드로 Chrome 공룡 게임을 즐길 수 있습니다. 있습니다. 소스 코드는 GitHub에서 확인할 수 있습니다. 다음 페이지에서 게임패드 폴링 구현을 확인해 보세요. trex-runner.js 드림 키 누름을 에뮬레이션하는 방법을 살펴보겠습니다.

Chrome 공룡 게임패드 데모를 실행하려면 핵심 Chromium 프로젝트에서 Chrome 공룡 게임을 제거했습니다( 조기 노력Arnelle Ballane)이 별도의 독립형 사이트에 배포하고 볼륨 낮추기와 진동 효과를 추가하여 기존 게임패드 API를 구현하고 전체 화면을 만들었습니다. 메훌 사타르데카르가 어두운 모드를 사용했기 때문에 있습니다. 즐겁게 게임하시기 바랍니다.

감사의 말씀

이 문서는 François Beaufort가 검토했으며 조 메들리. 게임패드 API 사양은 개발자가 스티브 아고스톤, 제임스 홀리어, 맷 레이놀즈 이전 사양 편집기는 브랜든 존스, 스콧 그레이엄, 테드 미엘차렉. 게임패드 확장 프로그램 사양은 브랜든 존스 히어로 이미지: Laura Torrent Puig