nodejsをAndroidモバイル端末にインストールして、他のモバイル端末とアドホック通信する

東京ゲームショウ2018のインディーズゲームブースにて[イセキクライマー](https://miyazaworks.jp/ruinsclimber/)というゲームの解説のお手伝いをさせていただきました。

ただゲームの解説するのもアレだと思ったので、青森出身という事を活かして津軽弁で解説するか、普通に標準語で解説するかをお客さんに選ばせてみようと思い、下記のようなガジェットを作って持っていきました。
※[イセキクライマー](https://miyazaworks.jp/ruinsclimber/)をプレイしていただいた大多数の方々にとっては、こんなもんあったっけ？となると思います。理由は後述いたします。

![DSC_0009.JPG](https://qiita-image-store.s3.amazonaws.com/0/3307/2c5db7c3-82cc-45e5-471a-d2e0694fea04.jpeg)
ただの板に手書きで書かれたようなボタンを触ると、板を見れる位置にいない対面の僕がどのボタンをタップしたのか分かる、という物です。
僕がお手伝いした[イセキクライマー](https://miyazaworks.jp/ruinsclimber/)が、一見デジタルに見えないコントローラーだったので、こういうガジェットも似合うんじゃないかな、と思い用意してみました。
#仕組み
中身はAndroidタブレットで、タップしたボタンに対応したメッセージを、nodejs がインストールされた Android スマホに送信しています。
タブレット上でアプリは起動していますが、画面全体を真っ黒な矩形を描画して覆っているため、紙を巻くとただの板に見えるようになります。
僕はスマホをお客さんの見えない位置に置いて、送られてきたメッセージをチラ見して確認し「かしこまりました！じゃあバリバリ津軽弁で話しますね！」とか「ちょっとだけ津軽弁交えて話しますね！」とかってのが出来るようになります。
#このガジェットの意味は？
無いです。
そろそろAndroidモバイル端末をサーバー化出来る時代って来てるんじゃないかな、って思ってググったら本当に方法があったので、作ってみたかっただけの物です。
#作り方
作り方としては色々あるのですが、一番簡単なのはスマホ側（押されたボタンがどれなのかを確認するための端末）にnodejsをインストールしておき、タブレット側にタップしたボタンがどれかをスマホに送信するアプリを作るだけです。
色々調べながらでも8時間くらいでスマホもタブレットも動くところまで出来たと思います。

Androidモバイル端末にnodejsをインストールする方法は下記の記事が分かりやすく、参考にさせていただきました。
[Androidでtermuxを使ってnode.jｓ+WEBサーバー](https://qiita.com/basictomonokai/items/30abb2e49ff960758f9a)
[AndroidスマホでNode.jsをマルチスレッド処理させてみた](https://qiita.com/dojyorin/items/978598790835d722f467)
[AndroidアプリとNode.jsで連携してHello World](https://qiita.com/Setz/items/b0036bad807164986975)

##termuxアプリのインストール
[termux](https://play.google.com/store/apps/details?id=com.termux&hl=ja)というアプリをインストールするだけで、PC程では無いにしてもめちゃめちゃいろんな事が出来るようになります。
termuxをインストールしたら、すぐにnodejsをインストールしてもいいのですが、開発をちょっと便利にするためのセットアップをしておくといいと思います。

##ストレージの操作が出来るようにしておく
アプリを起動した直後のディレクトリでも色々インストールやらなんやら自由に出来るのですが、エクスプローラー系のアプリからファイル群を確認しやすい場所で作業したい場合が多いと思います。
nodejsなので、モジュールのインストールやらなんやらstorageの操作を結構する事になると思うので、最初にtermux上から下記のコマンドを実行します。

```shell
$ termux-setup-storage
```

これでtermuxアプリにstorageを色々操作するための権限が付与されます。
ただ、これでもセキュリティの関係上 ls コマンドで中身が見れないディレクトリなど結構あるので、どこで作業すればいいのかググったりしながら調べながらやってみた方がいいと思います。
自分はよく分かってない事が多いので、なんとなく storage/shared/ の中に test_dir というディレクトリを作って作業してました。ここで Github のリポジトリをクローンしたりプルしたりします。

##コマンドを入力しやすくする
外部キーボードがあればそれでいいと思いますが、そうでない場合[Hacker's Keyboard](https://play.google.com/store/apps/details?id=org.pocketworkstation.pckeyboard)というアプリを入れておくだけで、結構事足りる気がします。（Tabキーが使えたり、Ctrlキーが押せたり、上下キーがあったり）

あと、ターミナルとかほとんど使った事が無いので知らなかったのですが、[fish shell](http://fishshell.com/)という物が凄い便利だったのでtermux上からインストールしておくといいと思います。（有名なヤツなんでしょうか？便利すぎて感動しました）

```shell
$ pkg install fish
```
でfish shellをインストールした後は

```shell
$ fish
```
で、モードが切り替わり、コードヒントみたいなのが出るようになったり、以前入力した物がヒントとして出てきてくれるようになります。しかもカラーリングされて。
（→キーかTabキーで入力補完も効きます）

##git のインストール
メインの開発はPC上で行いたかったので、PCで作ってGithubに上げた物をAndroidが受け取るという形にしました。

```shell
$ apt install git
```
これであとは git コマンドから Github に作ったリポジトリから clone したり pull したり。
僕は Github の Android クライアントは[OpenHub for GitHub](https://play.google.com/store/apps/details?id=com.thirtydegreesray.openhub)というのを使って clone するアドレスをコピペしたりしました。

##開発しやすい環境が整ったら nodejs のインストール
```shell
$ apt install coreutils
$ apt install nodejs
```
これで nodejs がインストールされて、npm とかも使えるようになります。
で、npm でのモジュールのインストールとかは PC 側でやって Github に上げた物を Android 側でプルした物を実行するっていう形が、あんまりプログラムを書かない自分にとってはやりやすいワークフローでした。

というか、termux上で `$ npm i babel -D (--save-dev) `ってしてもエラーが出てインストール出来なかったりしたので、なんとなくその形で開発を進める事になりました。
（端末によっては --save インストールが普通に出来るのかも？）

##アドホック通信っぽい事を実現するために
nodejsがインストールされた端末（スマホ）をテザリング状態にして、タブレット側からWifi接続すれば、スマホが「192.168.43.1（固定）」タブレットが「192.168.43.xxx（多分DHCP、固定にする事は不可能？）」というIPアドレスでLANが自動的に組まれます。
なので、この状態でタブレットに入れたアプリから「192.168.43.1」（+ポート番号）に自由にリクエストを送るだけ。

##バックエンド、フロントエンドのソースコードはGithubを参照
一応 nodejs の通信に関しては express を使って、コーディングを楽にするのに babel をインストールしたくらいです。

フロントエンド側（タブレット側）は慣れている Adobe AIR で行いました。（Electron とかも覚えなきゃ･･･）
ソースコードは全部 Github に上げてます。
https://github.com/yasurageruheya/DifficultyOfCommentaryForTGS
![DSC_0009.JPG](https://qiita-image-store.s3.amazonaws.com/0/3307/2c5db7c3-82cc-45e5-471a-d2e0694fea04.jpeg)
Adobe Animate で画面UIを作ったら、Android側でそれを表示させて、紙を載せてUIをマジックでなぞって描いただけです。
で、そのあと紙をクシャクシャにしてよりダサい感じにしたら、ボタン位置がUIに合うようにして巻いて、テープで貼り付けました。
Amazon の衝撃吸収のために入れられてるような綺麗じゃない紙を使ったので、もっと石っぽい感じになるかと思ったのですが、なんかイメージと違いました。はふん。
（青森の三内丸山イセキから出土したオーパーツ、という設定まで考えてました）

紙が巻けたら、タブレットが映し出すUIを隠すために、全画面に黒い矩形を描画するギミックもアプリに入れておく必要があります。

これで、ただの石の板に手で書かれたボタンを触っただけなのに、対面した僕にどのボタンを触ったのかバレる、という昔の手品みたいな事が出来ます。

#なぜ東京ゲームショウでこれを使わなかったのか
ビジネスデー初日の最初に使ってみたのですが、ビックリするくらい人が来てくれて、少しでも多くの人に[イセキクライマー](https://miyazaworks.jp/ruinsclimber/)を遊んでもらいたかったので、余計な解説を省くためこのガジェットは15分くらいですぐにしまいました(´；ω；｀)ﾌﾞﾜｯ
遊んでいただいた方々、本当に本当にありがとうございました！