カスタマイズネタでテトリスを扱うことがあるのですが、その時のベースに使っているのがこちらです:
https://github.com/dionyziz/canvas-tetris

Dionysis Zindros さんが HTML5 Canvas で作ったテトリスです。Canvas 、JavaScript 、そして CSS でテトリスが再現されていて、MIT ライセンスで公開されています。実際に遊ぶ時にもブラウザで index.html ファイルを開くだけ(index.html ファイルは HTTP サーバー上にアップロードされている必要はなく、ローカルファイルとして開くだけでも可)で遊べます。

一応、遊び方にも触れておきます。index.html ファイルをブラウザで開くと以下のような画面になります。この「Play」ボタンをクリックするとテトリスがスタートします:
2019061703


操作はキーボードを使います。矢印の左右でテトリミノ(ピース)を左右に移動、上矢印で回転、下矢印で強制的に下に移動します:
2019061704



といった背景もあって実際に遊ぶのはもちろん、改良する場合においても技術的&ライセンス的なハードルが低く、デモやハンズオンも含めたセミナーのネタとして重宝しています。


そんなわけで、今日のブログエントリはこのテトリスを Obniz で操作する、というカスタマイズの紹介です。


Obniz (オブナイズ)をご存じない人のために簡単に紹介しておきます。Obniz は 2017 年に Kickstarter でクラウドファンディングが開始された IoT ボードです。Arduino や Raspberry Pi(Zero) と比較しても小型で、単体ではダイヤル式のスイッチと簡単な文字が表示できるディスプレイを入出力装置として持っています。これ以外に標準で無線 LAN および Bluetooth につながることができ(そのための設定をダイヤル式スイッチで指定します)、そして 12 個の GPIO によって各種センサーやモーターを接続することができます。MicroUSB からの給電により、(単体では)最大 1.8A の電流で稼働します。

そして最大の特徴といえるのが JavaScript による API の提供です。HTML や Node.js から利用可能な JavaScript でこれらの入出力装置の状態を監視したり、値を入力/設定/出力することができます。Obniz の JavaScript そのものの紹介が本ブログエントリの目的ではないので、詳しくは公式ドキュメントを参照してください。ググればネット上にサンプルを含めた使い方がたくさん見つかりますが、要するに「ウェブ(ページ)との連携が容易なボード」なのです:
https://obniz.io/doc/root





この Obniz ボードとの連携として、ボードのダイヤルスイッチでテトリミノを動かせるように改良しました。そのコードがこちらです:
https://github.com/dotnsf/canvas-tetris


こちらのコードをダウンロード(または git clone)して、Obniz を WiFi に接続後にブラウザで index.html ファイルを開いてください。すると最初に以下のような画面になって Obniz ID の指定を促されるので所有する Obniz の ID を指定します:
2019061702


そして "Play" ボタンをクリックでゲームスタートです。ここでは Obniz のダイヤルスイッチを使って、以下のように操作することができます:
ダイヤルスイッチ操作
左に回す左移動
右に回す右移動
押し込む回転


実際に遊んでいる様子がこちらです(下手すぎるのは撮影しながらだから、です・・・):



この仕組みのすごい所は「ゲーム画面とコントローラー(Obniz)が離れていても実現できる」点です。↑の動画では Obniz のある場所でゲーム画面を開いていますが、たとえばゲーム画面は地球の裏側で見られていたり、コンサート会場の大型スクリーンなどに表示されていてもいいわけです。そんな仕組みを簡単に実現できてしまっている、という点が素晴らしいと感じてます。

ちなみにカスタマイズの肝となっている箇所のコードはこちらです。js/controller.js ファイル内に以下のコードを追加して、Obniz スイッチの変更イベントを obniz.switch.onchange でハンドリングし、その内容に応じて対応するキーが押されたようにイベントを発生させています:
  :
//. obniz
var obniz = new Obniz("XXXX-XXXX"); //. <-- Edit with your own Obniz ID
obniz.onconnect = async function(){
  obniz.display.clear();
  obniz.display.print( "Obniz TETRIS" );

  obniz.switch.onchange = function( state ){
    obniz.display.clear();
    obniz.display.print( state );

    switch( state ){
    case 'left':
      keyPress( 'left' );
      render();
      break;
    case 'right':
      keyPress( 'right' );
      render();
      break;
    case 'push':
      keyPress( 'rotate' );
      render();
      break;
    default:
    }
  }
}

この Obniz の JavaScript SDK は本当に強力で、簡単にこういうことが実現できちゃいます。LED やセンサーを繋いだり、モーターを繋いだりしなくても、手軽にこんな使い方が実現できちゃうという、このポテンシャルの高さが魅力で気に入ってます。