ゲームパッドで Chrome Dino ゲームをプレイする

Gamepad API を使用して、ウェブゲームを次のレベルに引き上げる方法を学びます。

Chrome のオフライン ページ「イースター エッグ」は、史上最悪の秘訣の 1 つです([citation needed]、 劇的な効果を主張)。Space キーを押すか、モバイルでは 恐竜をタップすると、オフライン ページがプレイアブル アーケード ゲームになります。ご存じかもしれませんが プレイしたいときにオフラインにする必要はありません about://dino にアクセスするか、about://network-error/-106 にアクセスしてください。ご存じでしたか? あることを 1 か月あたり 2 億 7,000 万件の Chrome 恐竜ゲームがプレイされています

<ph type="x-smartling-placeholder">
</ph> Chrome の恐竜ゲームが表示されている Chrome のオフライン ページ。 <ph type="x-smartling-placeholder">
</ph> Space キーを押すと、プレイできます。

ご存じない方もいるかもしれませんが、 アーケード モードでは、ゲームパッドでゲームをプレイできます。ゲームパッドのサポートは約 1 年前に追加されました ベスト プラクティスについては commit する期間: Reilly Grant。ご覧のとおり、このゲームは 完全に統合されているため、 オープンソース。イン この投稿では 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.01.0
  • buttons: ゲームパッドのすべてのボタンのボタン状態の配列。

なお、ボタンは、デジタル(押されている、押されていない)またはアナログ(たとえば、78% 押されている)のいずれかです。この ボタンが次の属性とともに GamepadButton オブジェクトとして報告されるのはこのためです。

  • pressed: ボタンの押下状態(ボタンが押されている場合は truefalse 押されていない場合は
  • touched: ボタンのタップ状態。ボタンがタップを検出できる場合は、 プロパティは、ボタンがタップされている場合は true、それ以外の場合は false になります。
  • value: アナログ センサーのボタンの場合、このプロパティは、 ボタンが押され、0.01.0 の範囲に線形正規化されます。
  • hapticActuators: 次を含む配列 GamepadHapticActuator 各オブジェクトは、コントローラで利用可能な触覚フィードバック ハードウェアを表します。

お使いのブラウザやゲームパッドによっては、 vibrationActuator プロパティである。次の 2 種類のランブル効果を使用できます。

  • デュアルランブル: ゲームパッドの各グリップに 1 つずつ、偏心した 2 つの回転質量アクチュエータによって生成される触覚フィードバック効果。
  • Trigger-Rumble: ゲームパッドのトリガーごとに 1 つのモーターが配置された、2 つの独立したモーターによって生成される触覚フィードバック効果。

次の概略図は、 仕様どおりである 汎用ゲームパッドでのボタンと軸のマッピングと配置を示しています。

<ph type="x-smartling-placeholder">
</ph> 一般的なゲームパッドのボタンと軸のマッピングの概要図。 <ph type="x-smartling-placeholder">
</ph> 標準的なゲームパッド レイアウトの視覚的表現 (出典)。

ゲームパッドが接続されたときの通知

ゲームパッドが接続されたタイミングを把握するには、ゲームパッドでトリガーされる gamepadconnected イベントをリッスンします。 window オブジェクト。ユーザーがゲームパッドを接続すると(USB または Bluetooth)、 GamepadEvent が呼び出され、適切な名前の gamepad プロパティにゲームパッドの詳細が格納されている。 以下では、私が横たわっていた 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 コントローラを外すと connectedfalse になりました。

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 つ以上接続されている場合、1 つのアイテムは null のみが可能です。必ずすべての項目について ゲームパッドは配列を「記憶」し、常に存在するとは限りません。 スロットが最初に空になります。

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

1 つまたは複数のゲームパッドが接続されていても、navigator.getGamepads()null アイテムを報告する場合、 「スリープ解除」する必要があるゲームパッドのボタンを押したままにできます。ゲームパッドをポーリングして、 ゲームループ内の状態を宣言する必要があります。

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.
}

デュアル ランブル

デュアルランブルは、触覚構成と 標準的なゲームパッドの各ハンドルに内蔵された偏心回転質量振動モーター。この構成では どちらのモーターでもゲームパッド全体を振動させることができます。2 つの質量は等しくないため、 それぞれの効果を組み合わせて、より複雑な触覚効果を作成できます。デュアルランブル効果は 次の 4 つのパラメータで定義します。

  • duration: バイブレーション効果の持続時間をミリ秒単位で設定します。
  • startDelay: バイブレーションが開始されるまでの時間を設定します。
  • strongMagnitudeweakMagnitude: より重い、および 0.01.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,
  });
};

トリガー ランブル

トリガー ランブルは、ゲームパッドのトリガーにそれぞれ 1 つのモーターが配置された 2 つの独立したモーターによって生成される触覚フィードバック効果です。

// 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,
  });
};

権限ポリシーとの統合

Gamepad API の仕様では、 ポリシー制御機能 文字列 "gamepad"。デフォルトの allowlist"self" です。ドキュメントの権限ポリシーでは、 そのドキュメント内のコンテンツに navigator.getGamepads() へのアクセスを許可するかどうか。無効になっている場合 そのドキュメント内のどのコンテンツにも navigator.getGamepads() の使用が許可されず、 gamepadconnected イベントと gamepaddisconnected イベントが発生する。

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

デモ

次の例は、ゲームパッド テスターのデモを埋め込みます。ソースコード Glitch で入手できます。接続してデモをお試しください ゲームパッドに USB または Bluetooth を使用し、ボタンを押すか、軸を動かす。

ボーナス: web.dev で Chrome dino をプレイ

こちらのゲームパッドで Chrome dino をプレイできます ありますソースコードは GitHub で入手できます。 次の場所でゲームパッド ポーリングの実装を確認してください。 trex-runner.js キー入力をエミュレートしている点に注目してください。

Chrome dino ゲームパッドのデモを行うには、 は、Chromium のコア プロジェクトから Chrome dino ゲームを取り除き、 以前の取り組みArnelle Ballane など)、これをスタンドアロン サイトに配置し、 ダッキング効果やバイブレーション効果を追加して既存のゲームパッド API を実装し、全画面表示を作成しました。 ダークモードを提供しました。Mehul Satardekar はダークモードを提供しました。 説明します。ゲームをお楽しみください!

謝辞

このドキュメントは François Beaufort によってレビューされ、 Joe Medley。Gamepad API の仕様は、 Steve Agoston 氏 James Hollyer Matt Reynolds。以前の仕様編集者は Brandon JonesScott GrahamTed Mielczarek。ゲームパッド拡張機能の仕様の編集 Brandon Jones。ヒーロー画像: Laura Torrent Puig 氏