サーバーと通信をする際によく使われるデータ形式の1つに「JSON」があります。 これを使って、APIやサーバー上のデータとやりとりができるようになります。 今回は、cocos2dxで、「JSON」を利用する方法を紹介したいと思います。
XMLを使って通信をする場合はこちら
【cocos2dx】XMLを利用してサーバーと通信する。 | albatrus.com
準備 - picojson
今回は「picojson」を利用してJSONの解析をおこないます。 Github : kazuho/picojson
まずは、こちらから「picojson.h」をダウンロードして下さい。
プロジェクトに追加
ダウンロードをしていただい「picojson.h」を、cocos2dxのプロジェクトに追加します。
これを読み込んで利用をします。
Android側でのエラー対応
Eclipseでビルドをすると3つのエラーが出ます。
これを解消させる必要があります。
[c]
//エラー内容
'isinf' was not declared in this scope picojson.h
'struct lconv' has no member named 'decimal_point'
[/c]
コードを以下のように変更します。 これでエラーが出なくなり、上手く動作するので多分大丈夫だと思います。 [c] //169 //isnan(n) || isinf(n) isnan(n)
//330 //char decimal_point = localeconv()->decimal_point; char decimal_point = ".";
//688 //num_str += localeconv()->decimal_point; num_str.push_back('.');
[/c]
準備2 - libcurl
libcurlを利用して、サーバーと通信をおこないます。
パスの設定 - Xcode
まずは[Build Settings]->[Search Paths]->[Header Search Paths]に以下のパスを設定して下さい。 [c] //パスを設定 $(SRCROOT)/../cocos2d/external/curl/include/ios [/c]
パスの設定 - Android.mk(Eclipse)
Android側でも、libcurlが使えるようにします。 これは、Android.mkに下記のように記述をします。 [c] //ネットワークが利用できるようにします。 LOCAL_WHOLE_STATIC_LIBRARIES += cocos_network_static [/c]
準備 - 読み込むJSONファイル
アプリで読み込む、JSONファイルを作成します。 [c] { "test": [ {"x": "alba", "y": "trus"}, {"x": "hogehoge", "y": "cocos2dx"} ] } [/c]
これをサーバーに設置します。 今回はDropboxを利用しました。
実装
JSONファイルの値を取り出すコードを書きました。 「cocos2dxのレシピ本」を参考にしています。 [c] static size_t onCurlWriteData(char ptr,size_t size,size_t nmemb,voiduserdata){
std::vector<char> *buff = (std::vector<char>*)userdata;
size_t sizes = size * nmemb;
buff->insert(buff->end(), (char*)ptr,(char*)ptr+sizes);
return sizes;
}
bool NetWorkLayer::getTextFromUrl(const char url,std::vector
CURL *curl;
CURLcode res = CURLE_FAILED_INIT;
curl = curl_easy_init();
if (curl) {
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,onCurlWriteData);
curl_easy_setopt(curl,CURLOPT_WRITEDATA,response);
res=curl_easy_perform(curl);
curl_easy_cleanup(curl);
}
if (res == CURLE_OK) {
CCLOG("res == CURLE_OK");
if(response->size()){
CCLOG("response -> size()");
return true;
}
}
return false;
}
void NetWorkLayer::getJsonValue(const char *url){
std::vector<char> responseData;
if (getTextFromUrl(url,&responseData)) {
std::string err;
picojson::value va;
picojson::parse(va, responseData.begin(), responseData.end(),&err);
CCLOG("get json 1 %s",err.c_str());
if (err.empty()) {
picojson::object &root = va.get<picojson::object>();
picojson::array &results = root["test"].get<picojson::array>();
picojson::array::iterator it;
CCLOG("get json 2");
for (it = results.begin(); it != results.end(); it++) {
picojson::object& text = it->get<picojson::object>();
//ここで値を取り出しています。 std::string& age = text["x"].get<std::string>(); std::string& name = text["y"].get<std::string>();
CCLOG("JSON 成功 %s",age.c_str());
CCLOG("JSON 成功 %s",name.c_str());
}
}
}
} [/c]
実際の利用する際にはgetJsonValue()にJSONファイルのURLを指定して下さい。 [c] void NetWorkLayer::networkJSON(){
//JSONファイルのURLを指定する
this->getJsonValue("http://dl.dropboxusercontent.com/..............");
}
[/c]
最後に
私がJSONなりXMLでサーバーと通信した理由は、アプリをアップデートしなくてもゲーム内容を変える仕組みが欲しかったからです。 とは言いましても、やりたい事は「広告の媒体の配信率を変える」ことです。 これは今色々なサービスがあるのですが、広告の媒体が限られているので、これを思い通りにできないかと考えています。
いかがでしたでしょうか? サーバ関係、JSONについてはこれまで触ったことがなかったので、コードなど不安です。 もし、もっと良い方法等あれば教えていただけると嬉しいです。
Cocos2d‐x開発のレシピ―iOS/Android対応 松浦 晃洋,齊藤 建二,古木 映治 秀和システム 売り上げランキング : 45730 Amazonで詳しく見る |