p5.js Web Editor上の処理で DualShock 4 の振動を扱う（Gamepad API を利用）

以下で扱っていた「p5.js Web Editor ＋ Gamepad API ＋DualShock 4（ゲームコントローラー）」の組み合わせに関する話です。

●p5.js Web Editor上で Gamepad API を使う： DualShock 4 を使ったシンプルな接続確認・ボタン押下判定 - Qiita
　https://qiita.com/youtoy/items/997e5720de790e36b98b

上記の記事では、ボタン押下の判定を扱いましたが、今回はゲームコントローラーの振動を扱います。

## ブラウザで振動を扱う API をいくつかピックアップ
ブラウザで、ゲームコントローラーの振動を扱えそうな　API を確認してみます。

### Gamepad API関連
MDN で検索すると、「Gamepad: vibrationActuator プロパティ」「Gamepad: hapticActuators プロパティ」という 2つが該当しそうでした。

それぞれのブラウザ対応状況を確認してみます。

#### vibrationActuator プロパティ
●Gamepad: vibrationActuator プロパティ - Web API | MDN
　https://developer.mozilla.org/ja/docs/Web/API/Gamepad/vibrationActuator

https://caniuse.com/mdn-api_gamepad_vibrationactuator
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/65b17ca4-503c-d4a3-3adc-436db5244f85.png)

#### hapticActuators プロパティ
●Gamepad: hapticActuators プロパティ - Web API | MDN
　https://developer.mozilla.org/ja/docs/Web/API/Gamepad/hapticActuators

https://caniuse.com/?search=hapticActuators
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/e479637c-3ee7-1816-fee3-5175720279a9.png)

それぞれ見てみると、以下のようです。

- 「Gamepad: hapticActuators プロパティ」： Firefox限定
- 「Gamepad: vibrationActuator プロパティ」： Firefox以外

今回、Chrome で試していこうと思うので、「Gamepad: vibrationActuator プロパティ」のほうを使っていきます。

この「Gamepad: vibrationActuator プロパティ」は、MDN のページで以下のように書かれているため、用途にはご注意ください。

:::note alert
非標準: この機能は標準ではなく、標準化の予定もありません。公開されているウェブサイトには使用しないでください。ユーザーによっては使用できないことがあります。実装ごとに大きな差があることもあり、将来は振る舞いが変わるかもしれません。
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/6462f766-bee4-42b9-d477-7ed1cfb057df.png)

## 試した内容
### 実装した内容
今回、p5.js Web Editor上でお試し用に実装した内容を示します。

```javascript
const sleep = (msec) => new Promise((resolve) => setTimeout(resolve, msec));

function setup() {
  createCanvas(600, 500);
  background(220);
}

function mouseClicked() {
  const gp = navigator.getGamepads()[0];
  if (gp?.vibrationActuator) {
    background(100, 150, 200);

    gp.vibrationActuator.playEffect("dual-rumble", {
      startDelay: 0,
      duration: 600,
      weakMagnitude: 1.0,
      strongMagnitude: 1.0,
    });
    changeBackground();
  }
}

async function changeBackground() {
  await sleep(600);
  background(220);
}

function windowResized() {
  resizeCanvas(windowWidth, windowHeight);
  background(220);
}
```

細かな部分の補足は、今回は省略します。

今回のポイントとなる部分は、以下です。

```javascript
  const gp = navigator.getGamepads()[0];
  。。。

      gp.vibrationActuator.playEffect("dual-rumble", {
      startDelay: 0,
      duration: 600,
      weakMagnitude: 1.0,
      strongMagnitude: 1.0,
    });
```

以下の playEffect() を使って、ゲームコントローラーを振動させています。

●GamepadHapticActuator: playEffect() method - Web APIs | MDN
　https://developer.mozilla.org/en-US/docs/Web/API/GamepadHapticActuator/playEffect

パラメーターの詳細は、上記のページをご参照ください。

### 処理を実行した時の様子
上記の処理を実行した時の様子は、以下のとおりです。

「画面をクリックすると、一定時間、キャンバスの背景色が変わり、その間はゲームコントローラーが振動する」という、一連の動作の流れが確認できました。
※ 上記の手順を進める前に、「ゲームコントローラーの接続」と「ゲームコントローラーのボタンをどれか押す操作」を行ってください

<iframe width="560" height="315" src="https://www.youtube.com/embed/5GuurbcV5Mc?si=O3x3aGTWD0a6GF-0" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>