【夏休みの工作に】obnizで動く遠隔対戦クソゲーを作ったよ



2020年8月8日開催 「[Obnizを楽しもう！2人1組の2人3脚型オンラインハッカソン](https://protoout.connpass.com/event/183228/)」で作成したクソゲーの作り方をご紹介します。

##作ったもの

私たちのチームにはジェイソン・ステイサムの熱狂的ファンの方がいましたので、スマホを振るという動作で、遠隔地にある現在のステイサムと若い頃のステイサムが対戦するという、分かる人にしか分からない意味不明なシュールなゲームを作りました。

![117322848_3214536365261542_7460646160235602154_n.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291592/6268a016-9809-e58a-c050-60d19abdafaa.jpeg)

なお、ハッカソンのときは、スマホを振るところは実装できなかったですが、ハッカソン後に改良しました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ステイサム vs ステイサム <a href="https://twitter.com/hashtag/protoout?src=hash&amp;ref_src=twsrc%5Etfw">#protoout</a> <a href="https://twitter.com/hashtag/%E3%82%B8%E3%82%A7%E3%82%A4%E3%82%BD%E3%83%B3%E3%83%BB%E3%82%B9%E3%83%86%E3%82%A4%E3%82%B5%E3%83%A0?src=hash&amp;ref_src=twsrc%5Etfw">#ジェイソン・ステイサム</a> <br>作り方はこちら　<a href="https://t.co/QBhmSIFqRl">https://t.co/QBhmSIFqRl</a> <a href="https://t.co/Zz5IGYF5gy">pic.twitter.com/Zz5IGYF5gy</a></p>&mdash; たつや @8/27 Developers Summit 2020 KANSAI (@tatsuya1970) <a href="https://twitter.com/tatsuya1970/status/1293570505698455557?ref_src=twsrc%5Etfw">August 12, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>



##環境
iOS 13.6 、12.4　では動作確認済み
新し目のAndoroidは動くと思いますが、動作未確認です。


##必要なもの

<img width="1271" alt="必要なもの.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291592/67b4bf49-6afd-f019-0ffc-cd895c0db54c.png">


- プラ目玉クリップ(M)6P（レモン株式会社） ２個　（100円ショップSeriaエールエール広島店で購入）
- ルミカ光るブレスレット ２個　（100円ショップSeriaエールエール広島店で購入）
- 若い頃のジェイソン・ステイサムの写真（インターネットより）
- 現在のジェイソン・ステイサムの写真（インターネットより）
- モバイルバッテリー　２個
- 空き缶　（アサヒスーパードライ）　２缶
- [マイクロサーボ SG-5010](http://akizukidenshi.com/catalog/g/gM-08913/) ２個
- モバイルバッテリーとobnizを結ぶケーブル　（USB Type-A　と　USB Type-C） ２つ
- [obniz board](http://akizukidenshi.com/catalog/g/gM-13685/)　２つ

※「夏休みの工作に」ってタイトルですが、よく考えたら、obniz boardって１個6000円もしますので、お子様はobnizを使わないやり方でやったほうがいいと思います。

##システム構成図
スマホ内蔵の加速度センサーからobnizクラウドへPOST通信しマイクロサーボを動かしています。
スマホを振ったかどうかはX軸だけで判定してます。
<img width="1259" alt="システム構成図.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/291592/ca129a38-f1ec-bc3b-2a1e-68ab7f42533d.png">


##コード

###スマホ側
```HTML:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<style>
    .hyouji {
    padding-top: 20px;
    font-size: 70px;
    text-align:center;
    margin:0 auto;
    }
</style>

</head>
 
<body>
<div id="txt">ここにデータを表示</div>            
<div class="hyouji">
 <div id="count">振った回数を表示</div>  
</div>  

<!-- 加速度の値を取得するプログラム 　こちらのサイトを参照　https://kkblab.com/make/javascript/acc.html　-->
<script> 
let aX = 0, aY = 0, aZ = 0;                    
let updown = 0, count = 0;

// 加速度センサの値が変化したら実行される devicemotion イベント
window.addEventListener("devicemotion", (dat) => {
    aX = Math.abs(dat.accelerationIncludingGravity.x);    // x軸の重力加速度（Android と iOSでは正負が逆）
    aY = Math.abs(dat.accelerationIncludingGravity.y);    // y軸の重力加速度（Android と iOSでは正負が逆）
    aZ = Math.abs(dat.accelerationIncludingGravity.z);    // z軸の重力加速度（Android と iOSでは正負が逆）
});
 
// 指定時間ごとに繰り返し実行される setInterval(実行する内容, 間隔[ms]) タイマーを設定
let timer = window.setInterval(() => {

    if (updown == 1 && aX < 2){
       updown = 0 ;
    }

    if (updown == 0 && aX > 8){
       updown = 1 ;
       count = count + 1 ;
    }
    //スマホを５回振ったときの処理
    if (count > 5){     
       count = 0;

       //obnizクラウドへPOST
       let value=[{"value":"なんでも可"}];//送るデータは何でもいい
      const url="https://obniz.io/events/XXXX/abcdefghijklmnopqrstuvwxyz/run"; //ここにobnizのURLを入力

       Promise.all(post(value,url))   
        .then((result) => {})
        .catch((result) => {});
    }

    displayData();      // displayData 関数を実行

}, 33); // 33msごとに（1秒間に約30回）
 
 
// データを表示する displayData 関数
function displayData() {
    let txt = document.getElementById("txt");   // データを表示するdiv要素の取得
    txt.innerHTML = "x: " + Math.round(aX) + "<br>"         // x軸の値
                  + "y: " + Math.round(aY) + "<br>"         // y軸の値
                  + "z: " + Math.round(aZ);                 // z軸の値
    
    let txt2 = document.getElementById("count");  
    txt2.innerHTML = count;
}

//POST通信  ここのを丸写し　https://www.it-swarm.dev/ja/javascript/%E3%83%95%E3%82%A9%E3%83%BC%E3%83%A0%E3%81%AA%E3%81%97%E3%81%A7post%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E9%80%81%E4%BF%A1%E3%81%99%E3%82%8B%E7%B4%94%E7%B2%8B%E3%81%AAjavascript/972618857/
function post(value,url) {
  let xhr = new XMLHttpRequest();
  xhr.open("POST", url, true);
  xhr.setRequestHeader('Content-Type', 'application/json');
  xhr.send(JSON.stringify({
    value: value
  }));
}

</script>
 
</body>
</html>
```
### obniz Cloud側
```HTML:obniz.html
<html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script src="https://obniz.io/js/jquery-3.2.1.min.js"></script>
  <script src="https://unpkg.com/obniz@3.7.0/obniz.js"></script>
</head>
<body>

<div id="obniz-debug"></div>
<h1>ServoMotor</h1>

<script>

const obniz = new Obniz("obnizIDを入力");

obniz.onconnect = async function () {
  var servo = obniz.wired("ServoMotor", {gnd:0, vcc:1, signal:2});
       obniz.display.clear();  //  ディスプレイを一旦クリアする
       servo.angle(60.0); // ここの角度を調整してください

    setTimeout(function(){
      servo.angle(0.0); 
    }, 1000);



}

</script>
</body>
</html>
```

##参考サイト
今回も先人の方々の知見のおかげでなんとか形になりました。
ありがとうございました。

- [スマホの加速度センサを使う（こくぶん研究室）](https://kkblab.com/make/javascript/acc.html)
- [フォームなしでPOSTデータを送信する純粋なJavaScript](https://www.it-swarm.dev/ja/javascript/%E3%83%95%E3%82%A9%E3%83%BC%E3%83%A0%E3%81%AA%E3%81%97%E3%81%A7post%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E9%80%81%E4%BF%A1%E3%81%99%E3%82%8B%E7%B4%94%E7%B2%8B%E3%81%AAjavascript/972618857/)