Cocos2d-xでGoogleスプレッドシートの表データをjsonで取得する
ぶっちゃけ今回は、あんまりCocos2d-x
は関係ないかもです。
他の言語とかでも全然使えるかと。
CocoStudio
のDataEditor
を使ってみたのですが、思った以上に使い辛い。。。
そして、そもそも何がしたいのか理解できず。
Excel
データを読み込んでJson
出力するだけ!!
以外の用途が汲み取れなかった。。。
そんなの他のツールとか一杯あるでしょ?ということで、Googleスプレッドシート使って色々やってました。
今回の流れは以下になります。
- Googleスプレッドシートにデータを定義して公開(公開先はお好みで)
- GoogleAppsScriptでスプレッドシートの内容をJsonに変換して返すAPIを作成(以後GASと略す)
- Cocos2d-xから
HttpRequest
で呼び出してレスポンスをdropbox/json11
で読み込む
参考
- とあるプログラマの備忘録 - Cocos2dx Http通信で外部DBから取得した値をpicojsonで解析する
- cocos2d-x本家github - HttpClientTest.cpp
- プログラマってこんなかんじ?? - Google Apps Script で spreadsheet のデータを JSON として読み込む
- Google Apps Scriptの開発手法まとめ
Googleスプレッドシートを作成
まず、表データ適当につくります。
公開します
「ファイル」 ー> 「共有」
変更を押す
自分の場合は、別に誰に見られても困らないのでとりあえずリンクを知っている全員
のやつにします。
※公開範囲は各自内容を確認してください適切に選んでください
GASを編集
GASを開く
スプレッドシートの「ツール」ー>「スクリプト エディタ...」を選択する。
「空のプロジェクト」を選ぶ
myFunctionを消して、以下のgist
のscriptをまるごと貼り付けます。
{book_id}
のところは自分のスプレッドシートのIDを入れてください。
IDは、スプレッドシートのURLに表示されてるやつです。
保存するとプロジェクト名を入れろと言われます。適当でいいです。
Googleスプレッドシートにデータを定義して公開
「公開」 ー> 「ウェブアプリケーションとして導入...」を選択
バージョンの説明を適当に入力して、「保存」を押す。
ユーザーは自分にする。これを変えるとURL叩く人はGoogleアカウント認証にリダイレクトされます。 (自分がかわりに実行してあげるイメージです)
アプリ実行は、誰でもOKにして「導入」を押す。
このURLをメモっておく(Cocos2d-xから呼び出します)
スクリプト認証
関数に「doGet」を指定して、スクリプトを実行する。
承認されてない警告が出てくる。続行する。
いつものGoolgeの認証でるので、承認する。
これでさっきのURLをブラウザとかで叩くとjsonがもらえるあとはこれをCocos2d-xから呼び出すだけ。
Cocos2d-xでHttpRequestでjsonを取得する
ちなみにバージョンは、Cocos2d-x 3.1
です。
dropbox/json11
の組み込みと使い方は、以前の記事「C++11でjson扱うならdropbox/json11がよさそう」を参考にしてください。
まあhpp
とcpp
をgithubから持ってきてClasses
ディレクトリ下に入れるだけです。
// 〜省略〜 #include "network/HttpClient.h" #include "json11.hpp" using namespace cocos2d::network; // 〜省略〜 // on "init" you need to initialize your instance bool HelloWorld::init() { ////////////////////////////// // 1. super init first if ( !Layer::init() ) { return false; } Size visibleSize = Director::getInstance()->getVisibleSize(); Vec2 origin = Director::getInstance()->getVisibleOrigin(); ///////////////////////////// // 2. add a menu item with "X" image, which is clicked to quit the program // you may modify it. // add a "close" icon to exit the progress. it's an autorelease object auto closeItem = MenuItemImage::create( "CloseNormal.png", "CloseSelected.png", CC_CALLBACK_1(HelloWorld::menuCloseCallback, this)); closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 , origin.y + closeItem->getContentSize().height/2)); // ★★★ ここから追加したMenuと押したときのHttpRequestの処理。コールバックでjsonをdump auto winSize = Director::getInstance()->getWinSize(); // Get auto labelGet = Label::createWithSystemFont("Test Get", "Arial", 22); auto itemGet = MenuItemLabel::create(labelGet, [this](Ref *sender) { HttpRequest* request = new HttpRequest(); // Google SpreadSheetの公開URL request->setUrl("https://script.google.com/macros/s/AKfycbyrMJ_T_N_D_25PniSQ60SbcJpz0Rmfb8XVaoIYW8CcTHjwj-U/exec"); request->setRequestType(HttpRequest::Type::GET); request->setResponseCallback([this](HttpClient* client, HttpResponse* response) { if (!response) { return; } if (0 != std::strlen(response->getHttpRequest()->getTag())) { CCLOG("%s completed", response->getHttpRequest()->getTag()); } long statusCode = response->getResponseCode(); auto statusString = StringUtils::format("HTTP Status Code: %ld, tag = %s", statusCode, response->getHttpRequest()->getTag()); CCLOG("response code: %ld", statusCode); if (!response->isSucceed()) { CCLOG("response failed"); CCLOG("error buffer: %s", response->getErrorBuffer()); return; } // dropbox/json11 dump data std::string responseString(response->getResponseData()->begin(), response->getResponseData()->end()); auto jsonData = json11::Json(responseString); CCLOG("response = %s", jsonData.dump().c_str()); }); request->setTag("GET test1"); HttpClient::getInstance()->send(request); request->release(); }); itemGet->setPosition(Vec2(Vec2(origin.x + visibleSize.width/2, origin.y + visibleSize.height/2))); // create menu, it's an autorelease object auto menu = Menu::create(closeItem, itemGet, NULL); menu->setPosition(Vec2::ZERO); this->addChild(menu, 1); return true; }
実行してボタンをクリックするとjsonを取得します。
ログに履かれたのが以下になります。
おわり
他にもいい方法あると思いますが、 Mac使ってるんでまずExcelはないなーということでスプレッドシートはちょくちょく使ってました。
DBをしっかり設計して紐付けるのも楽しいですが、 ゲーム作るという本来の目的を見失うことが多々あるのでこんな感じにサクッと導入するのが良いかなと思います。