All Articles

cocos2d-x(v3.2)で外部サーバの画像を取得してSpriteで表示する

外部サーバにある画像を取得したい

cocos2d-xでStaticなファイルが別の外部サーバにあって、それを取得して表示するケースを考えてました。 例えば、TwitterやFacebookのプロフィール画像とか、少なくとも初回は認証後にそれぞれのサービスから取ってこないといけないんですよね。

v3系はちょっとうまく行かなかった

ちょろちょろとググったりして、先頭の方でヒットする記事がありまして。

Cocos2d-xでサーバー上の画像を取得する方法

ここらを参考にさせていただきました。これはありがたい!

と思いきや、v3.2では動作せず…(´・ω・`)

Image(旧CCImage)::initWithDataの仕様が変わったようで

第一引数の型が変わったようで(Change Logが見つけられなかった)、そのままでは駄目でした。 で、以下のようにしたら取得できました。ついでにv3.2用にクラスとかも書き換えています。

#include "network/HttpRequest.h"
#include "network/HttpClient.h"
#include "network/HttpResponse.h"

using namespace cocos2d::network;

void HelloWorld::getExternalImage()
{
    HttpRequest* request = new HttpRequest();
    request->setUrl("http://example.com/external/image.png");
    request->setRequestType(HttpRequest::Type::GET);

    // CC_CALLBACK_2は面倒なのでラムダ関数でやる。httpresponce_selectorも古いみたい
    request->setResponseCallback([this](HttpClient *sender, HttpResponse *response) {
        if ( ! response->isSucceed() ) {
            return;
        }

        std::vector<char> *buffer = response->getResponseData();

        Image* image = new Image();
        // 今までは&(buffer->front())で良かったけど、unsigned charにキャストしないと駄目だった
        image->initWithImageData(reinterpret_cast<unsigned char*>(&(buffer->front())), buffer->size());

        Texture2D* texture = new Texture2D();
        texture->initWithImage(image);

        Sprite* sprite = Sprite::createWithTexture(texture);
        Size visibleSize = Director::getInstance()->getVisibleSize();
        Vec2 origin = Director::getInstance()->getVisibleOrigin();

        Size size = sprite->getContentSize();

        sprite->setPosition(Vec2((visibleSize.width + origin.x)/2,
                                 (visibleSize.height + origin.y)/2));

        this->addChild(sprite, 100);

        image->release();
        texture->release();
    });

    HttpClient::getInstance()->send(request);
    request->release();
}
</unsigned></char>```

<p>HttpRequest->Image->Textrure2D->Spriteの流れは変わりませんが、</p>

image->initWithImageData(reinterpret_cast<unsigned char*>(&(buffer->front())), buffer->size()); `

として、unsinged charにキャストしないといけないみたいです。うーんむずかしい。 あ、あとは一回取得できたら内部リソースに保存して、次からはそっちをロードするのが良いですね。

Gistにあげてますのでそちらも参考にどうぞ(このシンタックスハイライトC++は見づらいですね…)。

まとめ

v2->v3への変換はまだ過渡期ですね。早くv3系の世界線になって欲しいです。ラムダ関数が便利すぎて…。 実際、JavaScriptをメインに書く私にとってはラムダ関数はすごく直感的でわかりやすいです(一昔前のjQueryの匿名関数を乱発させているようでアレですが)。

現場からは以上です。