RPGツクールMVでデバイスのセンサを使う

この記事は、[RPGツクールMV Advent Calendar 2015](http://qiita.com/advent-calendar/2015/rmmv)の21日目の記事です。

RPGツクールMVでは、HTMLとJavaScriptで構成されているため、基本的にウェブでできる機能が簡単に扱えるのが魅力です。[^1]

[^1]: この記事を書く際に、ビデオやオーディオデバイスを使う事を試みたのですが、デスクトップ版では動く動きませんでした。

この記事では、デバイスのセンサを使って条件分岐を行うゲームを作ってみます。注意事項として、センサーの種類によってはデバイスによって動かないことがあり、重要なところで使うとゲームとして成り立たなくなってしまうので注意が必要です。

# デバイスの傾きセンサを使う
HTML5では、`devicemotion`イベントを使うことにより、デバイスの傾き情報を取得することが可能です。

前述のとおり、通常のWebフロントでの実装とそこまで変わりがありません。

今回は、傾きセンサを使って、特定の条件(デバイスをひっくり返した時に)、下のマップのAからBに移動するといった目的を達成したいと思います。
<img width="812" alt="TestProject.png" src="https://qiita-image-store.s3.amazonaws.com/0/33754/b798a346-424f-0f9d-818c-d1d12bf5a1f0.png">

# プラグインの作成

プラグインについては、既にいろんな記事でも書かれていますし、サンプルで幾つかのプラグインが入っているので、JavaScriptが読める人であればそこまで難しくないです。

注意事項として、JSのコメントにツクールMVのメーカーで表示される、また、変更できるパラメータの情報を記述します。

他にも`$gameVariables`でゲーム内の変数の操作ができたり、`Game_Interpreter.prototype.pluginCommand`でプラグインコマンドをフックできます。

今回はデバイスのセンサを使った以下のコードをライブラリとして追加しました。
お試し程度で作りましたが、傾きの閾値もパラメータで指定できるとで良いですね。

```js:ReverseDetect.js
//=============================================================================
// ReverseDetect.js
//=============================================================================

/*:ja
 * @plugindesc デバイスをひっくり返したことを検知します
 * @author miyukki
 *
 * @param variableId
 * @desc 変数ID
 * @default 0001
 *
 * @param detectEnabled
 * @desc 有効にするかどうか(プラグインコマンドでも有効にできます)
 * @default 0
 *
 * @help
 *
 * プラグインコマンド:
 *   ReverseDetect enable
 */

(function() {
  var parameters = PluginManager.parameters('TestPlugin');
  var variableId = Number(parameters['variableId']);
  var detectEnabled = Number(parameters['detectEnabled']) != 0;

  if (!window.DeviceMotionEvent) {
    alert("DeviceMotionEvent does not supported!");
  }

  window.addEventListener("devicemotion", function(e) {
    var z = e.accelerationIncludingGravity.z;
    if (z < -9.8 && detectEnabled) {
      $gameVariables.setValue(variableId, 1);
    }
  }, false);

  // Hook command
  var _Game_Interpreter_pluginCommand = Game_Interpreter.prototype.pluginCommand;
  Game_Interpreter.prototype.pluginCommand = function(command, args) {
    _Game_Interpreter_pluginCommand.call(this, command, args);
    if (command === 'ReverseDetect') {
      if (args[0] == 'enable') {
        detectEnabled = true;
      }
    }
  }
})()
```

# プラグインの追加と設定

「ツール」→「プラグイン管理」をクリックしてプラグインを追加していきます。
今回はどこでもイベントを検知するよう`detectEnabled`を`1`にしておきます。
傾きを検知すると、ここで指定した`variableId`に値`1`が代入されます。
![image](https://qiita-image-store.s3.amazonaws.com/0/33754/8984ed3c-3ddd-cb37-d30c-a37a7c4a893e.png)

# イベントの追加

マップ上のイベントを追加したい箇所に、イベントを追加していきます。
今回は全部で4ページ分のイベントを追加しました。4ページ使ったのは、センサの変数の反転を用意するためです。
（イベントの出現条件の変数がLarger Than以外もできるようになるといいなぁ…）

## 1. ひっくり返し検知(反転)を1にする
![image](https://qiita-image-store.s3.amazonaws.com/0/33754/c3dbad39-9e4e-7ce4-48fc-92d5c575b132.png)

## 2. ひっくり返し検知が1の場合、ひっくり返し検知(反転)を0にする
![image](https://qiita-image-store.s3.amazonaws.com/0/33754/d1b6a99a-a638-09d4-a832-8e19905a706c.png)

## 3. ひっくり返し検知(反転)が1の場合、エラーメッセージを表示する
![image](https://qiita-image-store.s3.amazonaws.com/0/33754/65bf80f0-da74-e843-f5e0-3a9a19603668.png)

## 4. ひっくり返し検知が1の場合、目的の動きをする(ここでは場所移動)
![image](https://qiita-image-store.s3.amazonaws.com/0/33754/5a0ff1f9-97a8-38c2-94a9-cb595c65cbe8.png)

# 実際の挙動
実際にどのような挙動になるのかを、動画にとってみました。
https://www.youtube.com/watch?v=RkkI5QFEqpw

# まとめ
今回、ツクールシリーズを初めて使ってみたのですが、MVからはJavaScriptでプラグインを書けるということもあり、簡単に複雑な動作やセンサを扱えるのがすごい便利な印象でした。