2013年3月1日金曜日

ウディタのダウンロード機能で Google スプレッドシートを読み書き

今回の記事はいつにも増して長くなってしまったので、まず要点だけまとめます。
以下のような内容です。
  • ウディフェスの「迷宮航路グラナドア」を遊んで、ウディタの「ダウンロード機能」に興味を持った。
  • ウディタの「ダウンロード機能」でサーバーに情報(文字列)を送信できる。
  • Google Apps Script を使うと、送られてきた情報をスプレッドシートに書き込んだり、メール・カレンダー等の Google のサービスで利用できる。
  • よってウディタの「ダウンロード機能」と Google のサービスは連携可能。
ウディタで Google スプレッドシートの内容を読み書きするサンプルツールを公開しています。
サンプル:ツール(左上の「ファイル」→「ダウンロード」からダウンロードできます)
サンプル:スプレッドシート

(ここから本文開始です)

ウディフェス出品作品をいくつかプレイしているのですが、そんな中で「迷宮航路グラナドア」というゲームに惹かれました。テキスト表示とネットワーク機能を使ったシンプルなゲームで、想像力を掻き立てられます。

このゲームではネットワーク機能でプレイヤーの情報を集めて、ランキングや他の人の行動履歴を表示してくれます。ランキングに載れるように頑張っているのですが、なかなか上位に行ける気配がありません。

そんな「ダウンロード機能」、つい最近ウディタのベータ版に加わった機能なんですよね。「ダウンロード機能」の名前の通り、サーバーからゲームの更新データなどをダウンロードする機能なのですが、ダウンロードをサーバーにリクエストする際にパラメーター(文字列)を送ることができます。受け取ったパラメーターを集計すれば、ランキングや行動履歴などをデータベースに格納したり、集計結果をウディタにダウンロードさせてランキングをゲーム内で表示したりできます。

これまではウディタ+外部プログラムでしか実現できなかったことを、ウディタの機能のみで実現できるようになったのですね。

そんなダウンロード機能を使ったゲームを楽しんでた時、ふと、先日音楽素材サイトのメールフォームを作る際に使用した Google Apps Script を思い出しました。 Google Apps Script を使えば、 Google のサービスでウディタの送信を受け取れるのではないかと思い立ったのです。そこで試してみたところ、上手くできました!

ウディタで作ったこちらのツールで、こちらのスプレッドシートに書き込み・読み込みが可能です。「名前」と「メッセージ」を入力し、スプレッドシートに送信すると同時に、最新の3件を読み込んでウディタに表示します。日本語も書き込むことができます(ひょっとしたら文字化けやエラーがあるかも)。

このスプレッドシートはブラウザで普通に開いたときには「閲覧のみ」可能となっていて、書き込みできません。でもウディタからの送信を受け取ることで、スプレッドシートに書き込むことが出来ます(ウディタ以外でも「get 送信」のパラメーターで書き込めます)。

また、スプレッドシートの内容をテキストデータでダウンロードさせることも出来るので、サーバー側のデータをウディタで読み込むことも可能です。

スプレッドシートをデータベースのように用いれば、ランキング・行動履歴などのネットワーク機能を実現できそうです。さらに、Google Apps Script はスプレッドシートだけでなく、メール・カレンダーなど Google のサービスにもアクセスできます。ウディタのダウンロード機能と Google のサービスが連携できちゃうんですね。工夫すれば色々面白いことが出来るかもしれません(アイディアさえあれば……)。

とりあえず機能として「出来る」という事は確かめられましたが、ネットワーク機能を使ったゲームを実際に開発・公開する場合は、 いろいろと気になる問題がありますよね。サーバーのアクセス速度とか、どのくらいのアクセス数まで許容されるのかとか。この辺はよく調べてから使う必要がありますね。

あと日本語文字列への対応に手間がかかる点は注意が必要です。ウディタのデータベースに文字コードテーブル(のようなもの)を持たせて、データ送信の際に文字列を変換(URLエンコード)して対応させました。もし興味のある方がいらっしゃいましたら、ウディタ制作部分は暗号化していないので、のぞいてみてください。ウディタに慣れていないので、変な書き方などあるかもしれませんが。

 Google Apps Script 側のコードは長くなるので下の方に掲載しています。

そんなわけで、最近ウディタベータ版に追加された「ダウンロード機能」と、最近サイト制作に使った Google Apps Script が連携できたという話でした。思わぬところで両者が結び付いて嬉しくなったので、記事を書き始めたらついつい長文に……。

参考サイト

WOLF RPGエディター公式サイト
Google Apps Script — Google Developers
Google Apps API Japan - Google グループ
初心者のためのGoogle Apps Scriptプログラミング入門
Google Apps Scriptプログラミング [中級編]
逆引きGoogle Apps Scriptリファレンス « bmoo.net
JIS X 0213:2000 関連データ

Google Apps Script のコード

このコードでは ecl.js を利用させていただいております(http://www.drk7.jp/MT/archives/001324.html)。
 Google Apps Script 内に ecl.js をコピーして用いる必要があります。
// *********************************************************
// get リクエストが来たときに実行される関数
// *********************************************************
function doGet(param) {
  // 受け取ったパラメータをスプレッドシートの2行目に書き込む
  inputParamToSheet(param, 2);
  
  // テキストにスプレッドシートの1行目から4行の内容を書き込む
  var output = ContentService.createTextOutput();
  output.append(outputSheetToCsv(1, 4));
  
  // get リクエストしてきたクライアントにテキストを返す
  return output;
}

// *********************************************************
// get 送信で受け取った param を
// スプレッドシートの row 行目に書き込む
// *********************************************************
function inputParamToSheet(param, row) {
  // 配列に受け取ったパラメーター param を代入
  var data = new Array();
  data[0] = new Array();
  data[0][0] = Utilities.formatDate(new Date(), "JST", "yyyy-MM-dd (EE) HH:mm:ss"); // タイムスタンプ
  data[0][1] = param.parameter.name;
  data[0][2] = param.parameter.message;
  data[0][3] = EscapeUTF8(param.parameter.name);
  data[0][4] = EscapeUTF8(param.parameter.message);

  // スプレッドシートの操作
  try{
    // スプレッドシートを指定して開く。
    // ここに指定するIDはスプレッドシートのURLで確認できる。
    var ss = SpreadsheetApp.openById('0AnSodraS19LadHd3VG1wWUFqb2hBOXp2eFg3UUswalE');
    Logger.log('open ' + ss.getName());
    var sheet = ss.getSheetByName('シート1');

    // row-1行目とrow行目の間に1行追加
    sheet.insertRowBefore(row);

    // 配列のデータをスプレッドシートに書き込み。
    // row 行1列目から1行×5列の範囲に書き込む。
    sheet.getRange(row, 1, 1, 5).setValues(data);    
  }catch(e){
    Logger.log(e);
  }
}

// *********************************************************
// スプレッドシートの row 行目から range 行読み込んで、
// csv 形式で出力
// *********************************************************
function outputSheetToCsv(row, range){
  // スプレッドシートの操作
  try{
    // スプレッドシートを指定して開く。
    // ここに指定するIDはスプレッドシートのURLで確認できる。
    var ss = SpreadsheetApp.openById('0AnSodraS19LadHd3VG1wWUFqb2hBOXp2eFg3UUswalE');
    Logger.log('open ' + ss.getName());
    var sheet = ss.getSheetByName('シート1');

    // スプレッドシートのデータを代入。
    // row 行1列目から range 行×5列の範囲を読み込む。
    var data = sheet.getRange(row, 1, range, 5).getValues();
  }catch(e){
    Logger.log(e);
  }

  // データを csv 形式の文字列にする。
  var csv = '';
  for(var i = 0; i < data.length; i++) {
    csv += data[i][0] + ',';
    csv += data[i][3] + ',';
    csv += data[i][4] + '\n';
  }

  return csv;
}