cocos2d-x 勉強第10回「ファイルを保存する」+「HttpRequest」

木内智史之介(シャッチョー)
ミンカさんけっこんしてくださいおねがいします(ズザー SEGAさん、DIVAの筐体ください(ズザー

今回の目標

ファイルを保存する必要性のあるアプリもあると思います。
僕なんかはゲーム系の開発に携わることが多いので、例えば画像データなどを端末側にダウンロードさせてしまって内部参照させるようなケースがまず思い浮かびます。
丁度いいので、そんな感じの想定で今回のお勉強、いってみたいと思うでござるよ!

下準備、下調べ

ググってみたところ

む?ファイル保存に関してはcocos2d::FileUtils::writeToFileを使用するイメージでいいのかな?
これは、前回の「変数の保存/永続化」 で使用したメソッドですね。

virtual bool writeToFile (
Dictionary * dict,
const std::string & fullPath
)

引数はDictionaryのみなのかなー。 単純にplainなテキスト(バイナリ含む)を保存するようなものはないのかしら?
そうすると、どうしたらいいものか…。

cocos2d::Image::saveToFileというメソッドがあるらしい

ほほう!そんなのもあるのか。

そもそもhttp通信ってどうやるんだろう?

  • HttpClient
  • HttpRequest
  • HttpResponse

あたりのクラスを駆使すればいけるのかな?

やってみる

HelloWorldScene.cpp

#include "network/HttpClient.h"
USING_NS_CC;
// snip...
bool HelloWorld::init()
{
// snip...
auto request = new extension::HttpRequest();
request->setUrl("http://befool.co.jp/images/logo_befool.jpg");
request->setRequestType(extension::HttpRequest::Type::GET);
request->setResponseCallback(this, httpresponse_selector(HelloWorld::onHttpRequestCompleted));
extension::HttpClient::getInstance()->send(request);
return true;
}
/** </div></div>
* ファイルDL終了コールバック
*/</span>
void HelloWorld::onHttpRequestCompleted(extension::HttpClient* sender, extension::HttpResponse* response)
{
Size visibleSize = Director::getInstance()->getVisibleSize();
Point origin = Director::getInstance()->getVisibleOrigin();
auto fileUtils = FileUtils::sharedFileUtils();
std::string filename = fileUtils->getWritablePath() + "hoge.jpg";
if (fileUtils->isFileExist(filename)) {
log("file exist. use hoge.jpg.");
auto sprite = Sprite::create(filename.c_str());
sprite->setPosition(Point(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));
this->addChild(sprite, 0);
} else {
log("no file exist. use default image, and save the file.");
if (response->isSucceed()) {
std::vector<char>* buffer = response->getResponseData();
auto* img = new Image();
img->initWithImageData(reinterpret_cast<unsigned char*>(&(buffer->front())), buffer->size());
img->saveToFile(filename.c_str());
auto* texture = new Texture2D();
texture->initWithImage(img);
auto sprite = Sprite::createWithTexture(texture);
sprite->setPosition(Point(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));
this->addChild(sprite, 0);
}
}
}
</pre></div></figure> ### 動かしてみる ![プレイ](play.png) よし! ## はまりポイント ### setRequestTypeが必須 デフォルトはGETっしょ?という甘い考えでは痛い目を見る。拙者のようにね! ``request->setRequestType(extension::HttpRequest::Type::GET);`` の指定は忘れないようにしよう。 ### cocos2d::Image::initWithImageDataの仕様変更が入った 最初は ``img->initWithImageData(&(buffer->front()), buffer->size());`` のように書いていたんだけど、どうにも型が一致しないようでコンパイルが失敗する。 http://www.cocos2d-x.org/forums/18/topics/35462 こちらのやりとりを参考にして、 ``img->initWithImageData(reinterpret_cast<unsigned char*>(&(buffer->front())), buffer->size());`` という内容にしたら通りました。 このあたりのキャストの方法とか``&(buffer->front())``のような書き方にどのような意味があるのか、まだイマイチ分かっていないでござるよ…。 const絡みであることは雰囲気から若干わかるような分からないような。。 ## 次回に向けて 今回は「ファイルの保存」と言いつつもそれが画像に限定されてしまった(しかもHttpRequestに関するところでガッツリ詰まった…)。 今度にでもplainなテキストを保存したい場合などどうすればいいのか調べなくちゃな。。 次回は「Web View」に関して試してみたいと思います! ### ソースコード https://github.com/8823-scholar/cocos2d-x-study/commit/184adf641cf68d908b2dee5c5150eefb44988eb8 ### 参考文献 - [Cocos2d-xでサーバー上の画像を取得する方法](http://taberenai-resipi.blogspot.jp/2013/11/cocos2d-x.html) - [How to save image by using HttpRequest in cocos2dx3.0?](http://www.cocos2d-x.org/forums/18/topics/35462) 感謝です!