【obniz 2022】#obniz と #p5js Web Editor と Joy-Con を組み合わせて動かしてみた！

## はじめに
この記事は、[obniz Advent Calendar 2022](https://qiita.com/advent-calendar/2022/obniz) の 15日目の記事です。

今回の内容は、以下のツイートで書いていたものの話です。

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

## 作ったものの概要
ツイートしていた動画の内容を補足すると、以下の通りです。

- 構成
   - デバイスは、obniz と Joy-Con と PC
   - Joy-Con と PC　は Bluetooth接続、obniz　のプログラムは p5.js Web Editor上で開発（開発に用いたページを、PC のブラウザで開いている状態）
   - ブラウザの Gamepad API を使って Joy-Con の入力を受けとる（※ ライブラリで gamecontroller.js を利用）
- 動作の流れ
   1. Joy-Con で特定のボタン（2種類）を押す
   1. ボタンが押された時のイベントをブラウザで受けとる
   1. ボタンが押された際に、ブラウザ上の p5.js のキャンバスに描画を行う（上記手順で押したボタンの種類によって、描画する図形が丸か四角のどちらかになる）
   1. p5.js のキャンバスの内容を obniz のディスプレイ上に表示させる

概要はこのようになるのですが、開発したプログラムの話へとうつっていきます。

## プログラム
今回、プログラムは p5.js Web Editor上で開発しています。

その環境でデフォルトで用意されるファイルは、HTML・CSS・JavaScript の 3種類があるのですが、今回は HTML と JavaScript にのみ変更を加えています。
以下では、それらの変更を加えた部分について、説明をしていきます。

### HTML
まず、HTML についてです。
今回は、obniz と、ブラウザの Gamepad API を扱いますが、それらを扱うための処理にライブラリを用いました。それらに関するライブラリの読み込みを加えたのが、今回の HTMLファイルでの変更点です。

```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://unpkg.com/obniz@3.24.0/obniz.js"
      crossorigin="anonymous"
    ></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
次に、JavaScript についてです。

ここで実装した主な処理は、以下の通りです。

- obniz に関するセットアップと接続の処理
- obniz のスイッチ操作時のログ出力処理（※ 動作確認用として実装）
- Joy-Con の特定の 2種類のボタンが押されたことを検知する処理
- Joy-Con の特定の 2種類のボタンが押された際に、p5.js のキャンバスや obniz　のディスプレイに描画を行う

プログラムを実行する際は、以下の中で「OBNIZ_ID_HERE」と書いている部分を、「ご自身の obniz の ID」に変更してから実行してください。

```javascript:sketch.js
const obniz = new Obniz("OBNIZ_ID_HERE", { local_connect: false });

let bgColor = "#aaaaaa";
const buttonList = ["button9", "button0"];

let canvas;

function setup() {
  canvas = createCanvas(128, 64);
  pixelDensity(1);

  obniz.onconnect = async function () {
    console.log(obniz.connectionState);

    obniz.switch.onchange = function (state) {
      if (state === "push") {
        console.log("pressed");
      }
    };
  };

  background(bgColor);

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

    gamepad
      .on(buttonList[0], () => {
        console.log("Button 12 still pressed...");
      })
      .before(buttonList[0], () => {
        console.log("Button 12 pressed...");
        rect(10, 10, 30, 30);
        rect(50, 10, 20, 20);
        obniz.display.draw(drawingContext);
      })
      .after(buttonList[0], () => {
        console.log("Button 12 was released");
        background(bgColor);
        obniz.display.clear();
      });

    gamepad
      .on(buttonList[1], () => {})
      .before(buttonList[1], () => {
        console.log("Button 14 pressed...");
        circle(width / 2, height / 2, height * 0.8);
        obniz.display.draw(drawingContext);
      })
      .after(buttonList[1], () => {
        console.log("Button 14 was released");
        background(bgColor);
        obniz.display.clear();
      });
  });
}

function draw() {}
```

こちらを、p5.js Web Editor上で実行すると、冒頭に掲載していた動画のようなことができます。

#### プログラムに関する補足
`obniz.display.draw(drawingContext);` という部分について、 obniz の Canvas API を使っていた事例だと、以下のようになっていました。

●ディスプレイ - obniz Docs
　https://obniz.com/ja/doc/reference/common/display
![ディスプレイ - obniz Docs](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/4543b8b8-d4c5-a414-c2c5-addb87757637.png)

これは p5.js だと、[drawingContext](https://p5js.org/reference/#/p5/drawingContext) を使うやり方になると思われたので、そのように実装して試しました。