現在cocos2d-xを用いて、サウンドノベル風のゲームを制作しています。
時間差で1文字ずつ文字が表示されるようにしたくて、CCLabelBMFontのサブクラスであるCCLabelAttributtedBMFontというクラスがあったので、このクラスを用いて実現しようとしました。
以下がCCLabelAttributtedBMFontのソースコードです。
https://github.com/gear1554/CCLabelAttr ... utedBMFont
このクラスを以下のように自プロジェクトで使いました。
#include "HelloWorldScene.h"
USING_NS_CC;
CCScene* HelloWorld::scene()
{
// 'scene' is an autorelease object
CCScene *scene = CCScene::create();
// 'layer' is an autorelease object
HelloWorld *layer = HelloWorld::create();
// add layer as a child to scene
scene->addChild(layer);
// return the scene
return scene;
}
// on "init" you need to initialize your instance
bool HelloWorld::init()
{
//////////////////////////////
// 1. super init first
if ( !CCLayer::init() )
{
return false;
}
string str = "昔昔。ある所に\nおじいさんとおばあさんが暮らしていました。\nおじいさんは山へ芝刈りに。おばあさんは川へ洗濯に行きました";
// create方法はCCLabelBMFontと同様でOK
attributeLabel = CCLabelAttributedBMFont::create(str.c_str(), "font.fnt");
attributeLabel->setAnchorPoint(ccp(0.0f, 1.0f));
attributeLabel->setPosition(ccp(0, CCDirector::sharedDirector()->getWinSize().height / 4));
// 5フレームに1文字送る設定
attributeLabel->setDispCycle(5);
attributeLabel->setDispSpeed(1);
addChild(attributeLabel,1);
//タイマー設定
this->scheduleUpdate();
return true;
}
//文字列長取得(マルチバイト対応)
int HelloWorld::lencalc(std::string str)
{
int result = 0;
unsigned char currentChar;
int byte = 0;
for (int i=0; str[i] != '\0'; i += byte) {
currentChar = str[i];
if(currentChar < 0x80){
byte = 1;
//cout << "バイト数 " << byte;
}else if(currentChar < 0xE0){
byte = 2;
//cout << "バイト数 " << byte;
}else if(currentChar < 0xF0){
byte = 3;
//cout << "バイト数 " << byte;
}else{
byte = 4;
//cout << "バイト数 " << byte;
}
result++;
}
return result;
}
void HelloWorld::update(float dt)
{
//init関数内で設定した文字列が全て表示されたら
if(attributeLabel->getIsAllCharDisplayed()){
//最初に設定した文字列を消去しようとしています
attributeLabel->removeAllChildren();
//新たな文字で改ページします
string str = "かきくけこ";
attributeLabel->setString(str.c_str());
int len = lencalc(str);
for (int i=0;i<len;i++) {
attributeLabel->getChildByTag(i)->setVisible(true);
}
this->pauseSchedulerAndActions();
}
}
最初に設定した文字列が全て表示されたかどうかをタイマーで逐一確かめています。
もし、全て表示されたら新たな文字列で上書きして、改ページをしたいのですが、
上記のコードだと、最初に設定した文字列全ての表示が終わり、それらの文字列が消えた後に、
新たに設定した文字列が表示され、それに続いて、最初に設定した文字列が新たに設定した文字列分消えて表示されてしまいました。
attributeLabel->removeAllChildren()では文字列は消す事はできないのでしょうか?