【完走賞ゲット-11】gamecontroller.js を p5.js Web Editor上で使ってみる（DualShock 4 との組み合わせ）

## はじめに
こちらは、[完走賞ゲットのため小ネタを毎日投稿しようとチャレンジする Advent Calendar 2022](https://qiita.com/advent-calendar/2022/youtoy) の 11日目の記事です。

[完走賞ゲットのため小ネタを毎日投稿しようとチャレンジする Advent Calendar 2022](https://qiita.com/advent-calendar/2022/youtoy) の [10日目の記事](https://qiita.com/youtoy/items/87c1c37b51ae9ef4ab4d)でも扱っていた「[gamecontroller.js](https://github.com/alvaromontoro/gamecontroller.js/)」の話です。

●【完走賞ゲット-10】gamecontroller.js を使って DualShock 4 を JavaScript で扱う - Qiita
　https://qiita.com/youtoy/items/87c1c37b51ae9ef4ab4d

この記事では、p5.js との組み合わせを試します。

## gamecontroller.js について
gamecontroller.js については、[完走賞ゲットのため小ネタを毎日投稿しようとチャレンジする Advent Calendar 2022 の 10日目の記事](https://qiita.com/youtoy/items/87c1c37b51ae9ef4ab4d)をご覧ください。

## gamecontroller.js を p5.js Web Editor上で動かす
### DualShock 4 を PC につなぐ
今回利用する DualShock 4 を PC に接続します（今回は USB接続にて）。

<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">ちなみに、接続は有線。<br>電波環境の悪いところでの展示などを考えると、有線と無線の両方が扱えるのはありがたい <a href="https://t.co/bS7SUIo435">pic.twitter.com/bS7SUIo435</a></p>&mdash; you (@youtoy) <a href="https://twitter.com/youtoy/status/1601358412234645504?ref_src=twsrc%5Etfw">December 9, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

### 簡単なお試し
まずは、gamecontroller.js が p5.js Web Editor上で動くことを確認します。

↓こんな感じのお試しをしてみて、コンソールに想定通りの出力が得られるのを確認できました。

https://twitter.com/youtoy/status/1601345488426786817

HTML と JavaScript の内容は、それぞれ以下の通りです。

```html:index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/gamecontroller.js@1.5.0/dist/gamecontroller.min.js"></script>
    <link rel="stylesheet" type="text/css" href="style.css">
    <meta charset="utf-8" />
  </head>
  <body>
    <main>
    </main>
    <script src="sketch.js"></script>
  </body>
</html>
```

```JavaScript:sketch.js
function setup() {
  createCanvas(400, 400);
  
  gameControl.on('connect', gamepad => {
  console.log('A new gamepad was connected!');
});
}

function draw() {
  background(220);
}
```

### ゲームコントローラーの操作を受けとる：ボタン押下
ゲームコントローラーとの接続が行えることは確認できたので、次はボタンを操作した時のイベントを発生させてみます。やってみたらできた、というのが以下のツイートです。

<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/p5js?src=hash&amp;ref_src=twsrc%5Etfw">#p5js</a> Web Editor上で、「gamecontroller.js」と「DualShock 4」を組み合わせて使う話の続き、キー操作も問題なく扱えそう。 <a href="https://t.co/YZ5T7uhGTe">pic.twitter.com/YZ5T7uhGTe</a></p>&mdash; you (@youtoy) <a href="https://twitter.com/youtoy/status/1601351058575757312?ref_src=twsrc%5Etfw">December 9, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

公式のページの情報をもとに、以下のような簡単なプログラムを作って試しました。

```javascript:sketch.js
function setup() {
  createCanvas(400, 400);

  gameControl.on("connect", (gamepad) => {
    console.log("A new gamepad was connected!");

    gamepad
      .on("button0", () => {
        console.log("Button 0 still pressed...");
      })
      .before("button0", () => {
        console.log("Button 0 pressed...");
      })
      .after("button0", () => {
        console.log("Button 0 was released");
      });
  });
}

function draw() {
  background(220);
}
```

### ゲームコントローラーの操作を受けとる：ジョイスティックの操作1（1方向のみ使う）
次に、DualShock 4 の左側にあるジョイスティックの操作を取得してみます。
以下のプログラムで、ジョイスティックを上方向に倒した時の操作を取得できました。

```javascript:sketch.js
function setup() {
  createCanvas(400, 400);

  gameControl.on("connect", (gamepad) => {
    console.log("A new gamepad was connected!");

    gamepad
      .on("up0", () => {
        console.log("Button 0 still pressed...");
      })
      .before("up0", () => {
        console.log("Button 0 pressed...");
      })
      .after("up0", () => {
        console.log("Button 0 was released");
      });
  });
}

function draw() {
  background(220);
}
```

ここまで試した内容を見ると、ボタン押下やスティックを倒したというイベントは、以下の 3状態のイベントがとれるようです。

- 操作をしている状態（操作をし続けている間は、連続してイベントが発生）
- 操作が行われた最初のタイミング
- 操作を終えたタイミング

#### ジョイスティックの操作からとれる情報について
ここで、ジョイスティックの操作からとれる情報について、少し補足します。
以下の Gamepad API関連の処理がテストできるサイトを使うと、ジョイスティックは倒したかどうかの二値だけでなく、どれくらいの傾きで倒したかというのもとれそうでした。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Gamepad API のテストに便利そう<br><br>●Gamepad Tester - Check Controllers and Joysticks Online<br>　<a href="https://t.co/jk44ZZxtvd">https://t.co/jk44ZZxtvd</a> <a href="https://t.co/kwUoB6X929">pic.twitter.com/kwUoB6X929</a></p>&mdash; you (@youtoy) <a href="https://twitter.com/youtoy/status/1601361942098350080?ref_src=twsrc%5Etfw">December 9, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

また、ジョイスティック関連の話ではない余談ですが、コントローラーを振動させるという動作も Gamepad API を使って行えるようでした。

https://twitter.com/youtoy/status/1601702161423167488

### ゲームコントローラーの操作を受けとる ＋ p5.js のキャンバス上で何か描画する
最後に、DualShock 4 の操作が行われた時に、p5.js での描画を何らか行うようにしてみます。
とりあえず、「背景の色を変える」・「図形を描画する」というのをやってみようと思います。

プログラムは以下の通りです。

```javascript:sketch.js
let bgColor = "#aaaaaa";

function setup() {
  createCanvas(500, 400);
  background(bgColor);

  gameControl.on("connect", (gamepad) => {
    console.log("A new gamepad was connected!");

    gamepad
      .on("button12", () => {
        console.log("Button 12 still pressed...");
        background("#0077ff");
      })
      .before("button12", () => {
        console.log("Button 12 pressed...");
      })
      .after("button12", () => {
        console.log("Button 12 was released");
        background(bgColor);
      });

    gamepad
      .on("button14", () => {
        console.log("Button 12 still pressed...");
        circle(width / 2, height / 2, 100);
      })
      .before("button14", () => {
        console.log("Button 14 pressed...");
      })
      .after("button14", () => {
        console.log("Button 14 was released");
        background(bgColor);
      });
  });
}

function draw() {}
```

なお、上記のプログラムを実行すると、このようになりました。

https://twitter.com/youtoy/status/1601929363897061376

## おわりに
完走賞ゲットのため小ネタを毎日投稿しようとチャレンジする Advent Calendar 2022 の10日目の記事で軽く試してみた gamecontroller.js を、今回は p5.js Web Editor上で扱うことができました。