戦うアプリニート

cocos2d-xやRuby on Railsの備忘録

cocos2d-x v3 Labelの一部の文字の色を変える

初のはてなブログです。唐突にcocos2d-xのTipsです。

常々、はてなブログ書きたいなあと思っていたので、
「あまり構えずに、思いついたときが吉日や! 新年やし!」
という勢いで書いてしまいたいと思います。

で、表題の件。Labelの一部だけ、色を変更したい時のTipsです。

RPGやADV風に1文字ずつ文字送りしていて、
重要なワードだけハイライトしたい時に使ってます。

「ええっ! プリンがなくなっていた!?」

みたいな感じで。

    Size visibleSize = Director::getInstance()->getVisibleSize();
    
    // Label
    TTFConfig conf_test("fonts/rounded-mplus-1m-regular.ttf", 48);
    auto lbl_test = Label::createWithTTF(conf_test, "「ええっ! プリンがなくなっていた!?」");
    lbl_test->setColor(Color3B::WHITE);
    lbl_test->setPosition(Vec2(visibleSize.width/2, visibleSize.height/2));
    this->addChild(lbl_test);
    
    // Menu
    auto btn_change_color = MenuItemFont::create("着色", [lbl_test](Ref* sender)
                                                 {
                                                     auto pu = lbl_test->getLetter(6); // プ
                                                     auto ri = lbl_test->getLetter(7); // リ
                                                     auto nn = lbl_test->getLetter(8); // ン
                                                     
                                                     pu->setColor(Color3B::RED);
                                                     ri->setColor(Color3B::RED);
                                                     nn->setColor(Color3B::RED);
                                                     
                                                 });
    btn_change_color->setPosition(Vec2(visibleSize.width/2, visibleSize.height/3));
    
    auto menu_test = Menu::create(btn_change_color, NULL);
    menu_test->setPosition(Vec2::ZERO);
    this->addChild(menu_test);

こんな感じです。

f:id:masahirosaito:20150103162004p:plain
f:id:masahirosaito:20150103162012p:plain

pu, ri, nnはSpriteです。

ポイントとしては、「プ」「リ」「ン」がそれぞれ7,8,9文字目なのですが、
Arrayのカウント的に0スタートなので、1小さいindexを渡します。

「ええっ! プリンがなくなっていた!?」
012345678

プログラムで動的にやるなら、lengthから1引く感じで。

    auto pu = lbl_test->getLetter(lbl_test->getStringLength()-1);
    pu->setColor(Color3B::RED);

あとは、一旦こうやって色を変えたLabelに、後からsetStringなどすると、index設定が残っていて
TextureAtlasが激おこで「Assertion failed!」とか言ってきます。

cocos2d: Assert failed: removeQuadAtIndex: Invalid index
Assertion failed: (index>=0 && index<_totalQuads), function removeQuadAtIndex,

この辺は根本までさかのぼれていないのですが、とりあえずの案としては、
新しい文字列の表示に移る前に、

    lbl_test->removeAllChildrenWithCleanup(true);

とすると大丈夫です。
ただ、負荷が高くなりそうなので、パフォーマンスを出したければもっと細かい制御が必要かもしれません。