RPGツクール用のMilkcocoaプラグインを作ってみた

前回(Milkcocoa Advent calendar 3日目にて)、RPGツクールMVが JavaScriptで動くってことなので、
Milkcocoaを使ってオンラインゲームが出来ないか、と試しに作ってみました。
[■前回の内容](http://qiita.com/m2wasabi/items/a2f286cf83725c59844e)

今回は、RPGツクールMV用のプラグインとして、それなりにコンテンツを作ることができるようになったので、
プラグインと、その使い方をご紹介します。

# Milkcocoaって何？
[Milkcocoa](https://mlkcca.com/)
サーバを設定・購入することなく簡単にリアルタイム通信ができるサービスです。
JavaScript,Node.JSを起点として、IoTデバイスとの連携など様々なプラットフォームに対応しています。
無料だと、20人同時接続まで使えます。
![mlkcca](https://qiita-image-store.s3.amazonaws.com/0/35009/3a3e8a0c-3cf2-77f2-a7bb-d5f6d4c6d8f6.png)


# プラグインについて
ソースコードは[GitHub](https://github.com/m2wasabi/milkcocoa-rpgmv-plugin)に公開しています。
何かそれっぽくなったので今後も暇を見つけて更新ていく予定です。

# 導入方法
## 1. 準備
事前に以下の準備を整える必要があります。
それぞれの手順は公式サイトにありますので、そちらに従ってください。

- [RPGツクールMV(体験版)](https://tkool.jp/mv/)のダウンロード・インストール
- [Milkcocoa](https://mlkcca.com/)のユーザー登録、アプリ作成
- RPGツクールMVでプロジェクトを新規作成する

## 2. プラグインの導入
### 2.1. milkcocoa.js の入手
MilkcocoaのCDNから、JavaScriptをダウンロードしてきます。
以下のリンクから「リンク先を保存」またはCliからwgetなどでダウンロードします。
https://cdn.mlkcca.com/v2.0.0/milkcocoa.js

プロジェクトのフォルダ内の`plugins`ディレクトリに`milkcocoa.js`を設置します。
> `js/plugins/milkcocoa.js`

### 2.2. プラグインのダウンロード
今回作ったものです。これをダウンロードします。
https://github.com/m2wasabi/milkcocoa-rpgmv-plugin/blob/master/src/js/plugins/MilkcocoaClient.js

### 2.3. OrangeCustomEvents プラグインのダウンロード
イベントをゲーム中に増やすために使用します。
http://download.hudell.com/OrangeCustomEvents.js

以下を参考にしました。
http://qiita.com/kyubuns/items/4108221a8b8245e46d27
http://forums.rpgmakerweb.com/index.php?/topic/46527-orange-custom-events/


## 3. 送信側htmlの作成
コントロールする側のhtmlを作成します。
処理の流れを説明すると、以下のようになっています。

Milkcocoaサーバに繋ぐ(app_idが必要)。
pathを指定してデータストレージを参照する。
データを受け取ったときのイベントを書く。
Milkcocoaのデータストレージに、JavaScriptのオブジェクトを投げる。

実際に投げているデータは、JavaScriptにベタで書いているので、ご参考ください。

```html:index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
    <title>milkcocoa message sender</title>
  </head>
  <body>
    <p><label>send message
        <input type="text" id="send" />
    </label>
    with Face type
    <select id="faceName">
    <option value="" selected="selected">---</option>
    <option value="Actor1">Actor1</option>
    <option value="Actor2">Actor2</option>
    <option value="Actor3">Actor3</option>
    <option value="Evil">Evil</option>
    <option value="Monster">Monster</option>
    <option value="Nature">Nature</option>
    <option value="People1">People1</option>
    <option value="People2">People2</option>
    <option value="People3">People3</option>
    <option value="People4">People4</option>
    </select>：
    <select id="faceIndex">
    <option value="0" selected="selected">0</option>
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
    <option value="4">4</option>
    <option value="5">5</option>
    <option value="6">6</option>
    <option value="7">7</option>
    <option value="8">8</option>
    </select>
    </p>

    <p><label>event swtitch [10]
        <button id="switchOn">On</button>
        <button id="switchOff">Off</button>
    </label></p>

    <p><label>event variable [11]
        <button id="setVar">=10</button>
        <button id="addVar">+1</button>
        <button id="subVar">-1</button>
        <button id="mulVar">*2</button>
        <button id="divVar">/2</button>
        <button id="remVar">%10</button>
    </label></p>

    <script src="https://cdn.mlkcca.com/v2.0.0/milkcocoa.js"></script>
    <script src="index.js"></script>
  </body>
</html>
```

```js:index.js
(function(){
    var app_id = 'YOUR_APP_ID';
    var path = 'YOUR_PATH';
    var clientId = '';
    var milkcocoa = new MilkCocoa(app_id + '.mlkcca.com');
    var ds = milkcocoa.dataStore(dataPath);

    // get event elements
    var sendInput = document.getElementById("send");
    var switchOnInput = document.getElementById("switchOn");
    var switchOffInput = document.getElementById("switchOff");
    var setVar = document.getElementById("setVar");
    var addVar = document.getElementById("addVar");
    var subVar = document.getElementById("subVar");
    var mulVar = document.getElementById("mulVar");
    var divVar = document.getElementById("divVar");
    var remVar = document.getElementById("remVar");

    // dosplay send data
    ds.on("send", function(data){
      console.log(data);
    });

    // events
    sendInput.addEventListener("keypress", function(e){
      if(e.keyCode == 13) {
        if(document.getElementById("faceName").value.length){
          var faceName = String(document.getElementById("faceName").value);
          var faceIndex = Number(document.getElementById("faceIndex").value);
          ds.send({message: {text:sendInput.value,faceName:faceName,faceIndex:faceIndex}});
        }else{
          ds.send({message: {text:sendInput.value}});
        }
      }
    });
    switchOnInput.addEventListener("click", function(e){
      ds.send({switch: {id: 10, value: 1}});
    });
    switchOffInput.addEventListener("click", function(e){
      ds.send({switch: {id: 10, value: 0}});
    });
    setVar.addEventListener("click", function(e){
      ds.send({var: {id: 11, value: 10}});
    });
    addVar.addEventListener("click", function(e){
      ds.send({var: {id: 11, action: 'add', value: 1}});
    });
    subVar.addEventListener("click", function(e){
      ds.send({var: {id: 11, action: 'sub', value: 1}});
    });
    mulVar.addEventListener("click", function(e){
      ds.send({var: {id: 11, action: 'mul', value: 2}});
    });
    divVar.addEventListener("click", function(e){
      ds.send({var: {id: 11, action: 'div', value: 2}});
    });
    remVar.addEventListener("click", function(e){
      ds.send({var: {id: 11, action: 'rem', value: 10}});
    });
  }());
```

## 4. ツクール側の設定

RPGツクール側で、Milkcocoaのプラグインを使用します。
まず、メニューバーから、「プラグインの設定」を開きます。
![メニュー](https://qiita-image-store.s3.amazonaws.com/0/35009/a5c5f96c-93aa-9da1-58dd-5bebe5878eef.png)

(必要があれば)`OrangeCustomEvents`と`milkcocoa`と`MilkcocoaClient`を読み込み、それぞれ有効にします。
![プラグイン設定](https://qiita-image-store.s3.amazonaws.com/0/35009/1d402d3b-ec32-0cf5-177b-84d241d162f2.png)



`MilkcocoaClient`の設定で、app_idと データストアのpathを設定します。
また、フィールドにキャラを同期させたい人は、`OrangeCustomEvents`の導入とともに
`MilkcocoaClient`の設定で、sendPositionを1に設定します。
![パラメータ設定](https://qiita-image-store.s3.amazonaws.com/0/35009/7610b768-2a8b-82c5-bea4-e94dbc129de3.png)



送信側のhtmlで、`スイッチ0010`をONにするイベントを発生させているので、
それをトリガーにしたイベントを作成します。
![イベント設置](https://qiita-image-store.s3.amazonaws.com/0/35009/52a8025f-b29e-f263-5861-0bbb3970b06d.png)

これは、`スイッチ0010`がONになることにより、フィールドに出現するクリスタルで、主人公が調べたら、所持金を+1して消えます(スイッチがOFFになる)



ブラウザを使って2つ同時に起動すると、それぞれのプレイヤーが見えているのがわかります。
また、パーティーの設定で先頭のキャラクターを変更すると、相手からの見た目も変わります。
![マルチプレイ](https://qiita-image-store.s3.amazonaws.com/0/35009/c2424560-670c-758a-7a79-6c5a9a6eecb4.png)


Milkcocoaを使うと複数の人に台詞を同時に展開できます
![台詞](https://qiita-image-store.s3.amazonaws.com/0/35009/30a038b8-972e-3c2f-9411-96dadc9fda27.png)


今回は変数の四則演算もできます
![変数](https://qiita-image-store.s3.amazonaws.com/0/35009/60878149-5a9f-09ac-1e4f-dff48c17cfdb.png)


プラグインコマンドで、ツクール側からメッセージの送信が可能です。
コマンドのリファレンスはプラグインのヘルプをご覧ください。
![プラグインコマンド](https://qiita-image-store.s3.amazonaws.com/0/35009/9f2e2df4-3bfc-ffb8-f86a-fc25adcc7ba6.png)

デモを以下に設置しています。
RPG側
http://m2wasabi.github.io/milkcocoa-adv-20151203/
HTML側
http://m2wasabi.github.io/milkcocoa-adv-20151203/sender/

## 5. Let's construction
フラグ起動で強制参加イベント作ったり、1人しか取れないアイテムを設置したりできるので夢が広がります。

## 今後のバージョンアップ予定
+ 現在は、フラグの値をオンライン記憶する機能が無いので、データを保存して同期できるようにする(データ量に気を付けながら)
+ 任意のデータを保存・呼び出しできるようにする

## おわりに
自分でもビックリするほど簡単に扱えるようになりました。
フラグと台詞共有できるので、TRPGみたいなのが、できますね！

それでは、良いツクールライフを！