光センサで遊ぶ「かくれんぼ」をobnizとp5jsで作ってみた

#かくれんぼしたい
皆さんは小学生の頃は何をして遊ぶ子供でしたか？
僕は__かくれんぼ（with DSのピクトチャット）__か__ドッジボール__か__デュエルマスターズ__をやっていました。
今考えると体力本当に無限大だったなあと懐かしい気分になります。

先日人生初のハッカソンに出場しまして（@Toshiki0324 さんありがとうございました！！）、あるチームがobnizとp5jsとを組み合わせたゲームを作っていました。
obnizで物理的な動作を検知しインタラクティブにp5jsで描画する、という発想に関心が沸き、今回は勉強もかねて__自宅でも全力でかくれんぼ__できるゲームをp5jsで作ってみました。
ただのかくれんぼでもつまらないので、__背景に隠れながら逃げるかくれんぼ__を作ってみました。

コードはGistに載せてありますので是非是非実装してみてくださいね。
アプリもデプロイしたのでURLから遊びに行ってみてください。
obnizがあっても無くても遊べるようにしてます。

コード全体は⇒[こちら](https://gist.github.com/canonno/05fb889dc0bb80b79fdf8149f35c80f7)

光センサで遊ぶなら⇒[こちら](https://affectionate-edison-a21421.netlify.app/kakurenbo_hikari.html)
超音波センサで遊ぶなら⇒[こちら](
https://affectionate-edison-a21421.netlify.app/kakurenbo_kyori.html)
obniz無しで遊ぶなら⇒[こちら](
https://affectionate-edison-a21421.netlify.app/kakurenbo.html)
※配線情報は後ほどの章で掲載しているので確認よろしくお願いします！

#完成デモ
##基本ルール
かくれんぼと同じく、鬼から隠れつつ逃げつつ生き延びていくゲームとなっています。
ゲームの特徴として、__プレイヤーは自身の色を操作することができ、背景の色に隠れることができます__。
何日まで生き延びたらクリアとかはなく、タッチされるまでの最長生存記録を目指すものとなっています。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">影になりながら逃げるかくれんぼのゲーム作りました。<br>プレイヤーは影になり背景に隠れながら鬼から逃げます。<br>obniz光センサにつないで手で影を作れば色を変えられます。<br>もちろんobnizを使わなくても遊べます。<br>day5夜を越えられなかったので、超えられたら教えてください<a href="https://twitter.com/hashtag/obniz?src=hash&amp;ref_src=twsrc%5Etfw">#obniz</a><a href="https://twitter.com/hashtag/p5js?src=hash&amp;ref_src=twsrc%5Etfw">#p5js</a><a href="https://twitter.com/hashtag/javascript?src=hash&amp;ref_src=twsrc%5Etfw">#javascript</a> <a href="https://t.co/S3Y1kzpjyq">pic.twitter.com/S3Y1kzpjyq</a></p>&mdash; canonno (@canonno_blog) <a href="https://twitter.com/canonno_blog/status/1293361014549823490?ref_src=twsrc%5Etfw">August 12, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

__鬼はプレイヤーが近くにいたり、背景から浮いていたら全力で追いかけてきます__。
鬼の色が真っ黒なので、夜の時間はプレイヤーも鬼もものすごく見にくくなります。
その間も鬼は動き回るので、夜の間につかまってしまうことが大多数だと思います。
__いかに夜をうまく超えるか__、という部分がポイントのゲームになっています。

また、__一日過ぎるごとに鬼はスピードが上がっていきます__。
一日目はゆるゆる動く鬼ですが、五日目ぐらいになると最初の二倍近い速さで動き回ることになります。
その鬼からいかに隠れて逃げ回るか戦略が試されるゲームとなっています。


#プレイヤー操作
##プレイヤー移動
__プレイヤー移動はキーボードの十字キー__となってます。
右手はキーボードでプレイヤー移動、左手でプレイヤーの色操作が基本になっています。

##プレイヤー色操作
プレイヤーの色操作はやり方が3通りありまして、
・光センサー
・超音波センサー
・キーボード操作
となっています。
それぞれ紹介していきますね。

###光センサー
まずはコンセプトに沿うように光センサーで操作する方法です。
__光センサーを手で覆うとプレイヤーが黒くなり、手を離すとプレイヤーが白くなります。__
程よい色を維持する場合は、絶妙に光を入れ続ける必要があり、なかなか高難易度になっています。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">光センサを使って操作するときのポジション<br>部屋が暗すぎるとプレイヤーが無限に黒くなって背景に隠れられなくなって詰みます。 <a href="https://t.co/8nDpXnsMVQ">pic.twitter.com/8nDpXnsMVQ</a></p>&mdash; canonno (@canonno_blog) <a href="https://twitter.com/canonno_blog/status/1293363933915439105?ref_src=twsrc%5Etfw">August 12, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

今回使ったセンサーはCdSセル5mmタイプ、抵抗は330Ωを使っています。（参考：[秋月電子](http://akizukidenshi.com/catalog/g/gI-00110/))
写真のように配線をしてご利用下さい（赤：0へ、白：1へ、黒：2へ接続）。![DSC_0066.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666990/f87b1a3c-75d6-f8dd-3951-0f9df5c35568.jpeg)
![DSC_0067.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666990/3ba307d9-2f3c-ffc1-f972-3da4e3ef428f.jpeg)

光センサを利用したゲーム入り口は⇒[こちら](https://affectionate-edison-a21421.netlify.app/kakurenbo_hikari.html)

###超音波センサー
次に超音波センサーを利用した方法です。
なぜ超音波センサー？と思ったかもしれませんが、当初「obnizとp5jsのインタラクティブなゲーム」とだけ考えており、超音波センサーを使おうが最初に思い浮かびました。
その中で「あれ光センサー使ったほうがコンセプト通りじゃね？」となり、両方実装しました。
__超音波センサーから物体への距離が小さくなるとプレイヤーは黒くなり、距離が大きくなるとプレイヤーは白くなります。__

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">当初は超音波センサで実装してましたが、いや光の方がそれっぽくね？ということで途中で方向転換しました。<br>超音波センサでも一応操作できます。 <a href="https://t.co/PxoaDvmGAl">pic.twitter.com/PxoaDvmGAl</a></p>&mdash; canonno (@canonno_blog) <a href="https://twitter.com/canonno_blog/status/1293364502004559872?ref_src=twsrc%5Etfw">August 12, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

今回使った超音波センサーはHC-SR04です。(参考：[秋月電子](http://akizukidenshi.com/catalog/g/gM-11009/))
超音波センサーは配線というよりはそのままobnizに接続すると操作しやすかったです。

![DSC_0068.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666990/75b14237-a61e-931d-e19d-843301554b5a.jpeg)

超音波センサーを利用したゲーム入り口は⇒[こちら](
https://affectionate-edison-a21421.netlify.app/kakurenbo_kyori.html)


###キーボード操作
obniz持っていない方、このセンサー類を持っていない方に、obnizを使わないでキーボード操作のみでもできる設定を用意しています。
プレイヤーの色調整は
　__Aキー：影に近づく(黒くなる)
　Fキー：光に近づく(白くなる)__
となっております。

obnizでの色調整は結構繊細なので難しく、最初はこちらで要領をつかむのが良いかもしれません。
是非キーボードオンリーでも挑戦してみてくださいね。
キーボードオンリーのゲーム入り口は⇒[こちら](https://affectionate-edison-a21421.netlify.app/kakurenbo.html)


#実装こまごま
##ブラウザとobnizの連携
node.jsでobnizと接続したことはありましたが、html中にjsとして埋め込むのは初めてでした。
html部分の実装はこちらです。
↓こちらをかなり参考にさせていただきました。
https://qiita.com/JINPLAYSGUITAR/items/3bcee02d8a612544c06e

```html
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
  <script src="https://unpkg.com/obniz/obniz.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.1/p5.js"></script>
</head>
<body>
<div id="obniz-debug"></div>
<script>

//ここに処理を書く

</script>
</body>
</html>
```
デプロイして他の人に自分自身のobnizで楽しんでもらいたいと思いました。
html側でinputとかbuttonとかいるのかな？と思っていたんですがobnizオブジェクトを作ったときに勝手にポップアップを表示してくれるようです。
もしかしたらobniz_idの一文すらいらないかも・・・？

```js

    //obniz Idをインプットしてもらう
    var obniz_id = document.getElementsByName("obniz_id");
    var obniz = new Obniz(obniz_id);
    
    //照度の取得
    var hikari = 0.2;
    obniz.onconnect = async () => {
    obniz.io0.output(true); //io0を5vに(電気を流す)
    obniz.io2.output(false); //io2をGNDに(電気を逃がす)

    //io1をアナログピンに(センサーの値を取得)
    obniz.ad1.start((voltage) => {
        //センサーの値が変わるたびに実行される
        hikari = voltage;
    });
}
```

##obnizとp5jsとの連携
最初はobnizと連携した後にp5jsを描画するので、obniz.onconnect = async () =>の後に描画処理をいれるのかな？と思っていました。
処理もobniz.onconnectのところで止まってしまうんじゃないか・・・？と思って色々試行錯誤しました。

```js
    //obniz Idをインプットしてもらう
    var obniz_id = document.getElementsByName("obniz_id");
    var obniz = new Obniz(obniz_id);
    
    obniz.onconnect = async () => {
    //処理がここで止まって
    });
}

//ここから先の処理が進まないんじゃないか？と思ってました
```
試行錯誤の結果、どうもきちんとonconnect以降の処理も走ってくれるようです。
obnizの処理とゲーム側の処理を別々に書いても問題ない様子。
これはらくちんですね。

```js

    //obniz Idをインプットしてもらう
    var obniz_id = document.getElementsByName("obniz_id");
    var obniz = new Obniz(obniz_id);
    
    //照度の取得
    obniz.onconnect = async () => {
      //ここを処理しつつ
    });
}
    //ここ以降も処理を走らせてくれるみたいです
    function setup(){
    //読み込み時の処理
    }
    function init(){
    //ゲームの初期化の処理
    }
    function draw(){
    //ゲーム中、常にここの処理が実行
    }

```
ただ変数のスコープで混乱しないように注意してくださいね。
今回色々試行錯誤する中で一番多かったのが変数のスコープの定義ミスでした。
もし思い通りの動作をしないなと思ったときは、今一度変数のスコープを確認してみてください！

コードの全体はGist([こちらから](https://gist.github.com/canonno/05fb889dc0bb80b79fdf8149f35c80f7))に載せてあるので、是非ご覧になってくださいね。

#今後やりたいこと
p5js面白い！色んな可能性を感じるライブラリですね。
最近ブラウザを利用すればスマホの各種センサ類にアクセスできることを勉強したので、スマホの加速度センサとか使いながら何かゲーム作れないかなとか考えています。

最後までご覧いただきありがとうございました！
LGTMつけていただけると励みになりますので、よろしくお願いいたします！