如何在Cocos2dx中为ProgressTimer的Sprite添加Label?

时间:2015-04-26 22:49:50

标签: c++ cocos2d-x cocos2d-x-3.0

我试图让ProgressTimerSprite一起使用Label作为孩子。似乎只有Sprite并且它的子节点都没有被用作进度条的精灵。

我已经创建了标签,将其添加到精灵中。我将精灵添加到ProgressTimer和场景中,因为我想确保它看起来很好看。从场景中删除标签并仅将其提供给ProgressTimer似乎没有做任何不同的事情。

然后我使用ProgressTimer创建Sprite,配置它,然后将其添加到我的场景中。

我已经简要地研究了如何使用RenderTexture创建一个纹理并将其传递给一个Sprite并从那里开始工作,但是在看到一个模糊的颠倒mysprite.png之后没有任何地方。

如何让Label中的Sprite显示在我的场景中的ProgressTimer上?

//init label
Label* lbl = Label::createWithTTF("My label", "fonts/Marker Felt.ttf", 24);
lbl->setTextColor(Color4B::RED);

//init sprite
Sprite* sprite = Sprite::create("mysprite.png");
sprite->addChild(lbl);

scene->addChild(sprite); //make sure it works normally

auto progress_timer = ProgressTimer::create(sprite);

progress_timer->setScale(1.5);
progress_timer->setPercentage(100);

scene->addChild(progress_timer);

3 个答案:

答案 0 :(得分:2)

最简单的解决方案是使用ProgressTimer,并在构建时嵌入标签(作为资产资源的一部分),或者如果要动态更改标签,则使用RenderTexture。

我已经看到一些游戏的标签和进度背景总是可见的,只是让酒吧自己填满。通常情况下,当它是健康栏或加载时,您可能希望查看添加背景,以便在进度填满时标签看起来并不奇怪。

您还可以使用ClippingNode或自定义命令来构建自己的精灵+标签进度计时器。标签基本上是spritebatch中的一组精灵。这虽然有点工作。

使用RenderTexture,如下所示:

Size size = sprite->getContentSize();

auto rt = RenderTexture::create(size.width, size.height, Texture2D::PixelFormat::RGBA8888);
rt->setAutoDraw(true);
rt->addChild(sprite);
rt->addChild(label);
auto rtSprite = Sprite::createWithTexture(rt->getSprite()->getTexture());
ProgressTimer* progress = ProgressTimer::create(rtSprite);

答案 1 :(得分:1)

感谢@ SteveTranby的解决方案,我找到了一个适合我的解决方案。设置AutoDraw的问题在于我相信它希望预定更新能够运行,因此除非您在导演的渲染器上调用render,否则它实际上不会渲染任何内容,因此我采用手动操作画到精灵。

我也遇到了失真问题,因此我禁用了抗锯齿功能,并确保我根本不进行任何缩放。我将锚点设置为1,1因为0,0的默认值会切断图像的一半,然后我也不得不翻转图像。我不确定为什么。

//sprite for base layer
auto prog_sprite = Sprite::create("progbar.png");
auto fmt = prog_sprite->getTexture()->getPixelFormat();
auto size = prog_sprite->getContentSize();

auto lbl = Label::createWithTTF("label text", "fontpath, size.height);
lbl->setTextColor(Color4B::RED);

//sprite for label
auto lbl_sprt = Sprite::create();
lbl_sprt->addChild(lbl);
rt = RenderTexture::create(size.width, size.height, fmt);

rt->begin();
//draw base sprite to texture
prog_sprite->getTexture()->setAliasTexParameters();
prog_sprite->setAnchorPoint(Vec2(1, 1));
prog_sprite->setPosition(size.width, size.height);
prog_sprite->visit();

//draw label sprite to texture
lbl_sprt->setAnchorPoint(Vec2(1, 1));
lbl_sprt->setPosition(10, 10);
lbl_sprt->visit();
rt->end();

//create a sprite from the new texture
Texture2D* text2d = rt->getSprite()->getTexture();
text2d->setAliasTexParameters();
auto final_sprite = Sprite::createWithTexture(text2d);
final_sprite->setFlippedY(true);

//create the final progresstimer
this->prog_timer = ProgressTimer::create(final_sprite);

纹理之前的精灵上的大多数方法,例如锚点和翻转,似乎并不重要。位置呢。

请注意,如果您已经在调用setPercentage之后在ProgressTimer上setSprite,则需要将其设置为其他值,然后再将其设置为,以便内部精灵/纹理得到更新。我认为这是一个错误,所以要小心。

答案 2 :(得分:0)

我最近重新解决了这个问题,并找到了一个实际的解决方案。事实证明@SteveTranby最初没有使用renderTexture。

auto lbl = Label::createWithTTF("label string", my_font_name, 25);
lbl->setAnchorPoint(Vec2(0.5f, 0.5f));
auto front_size = my_progress_timer->getContentSize();
lbl->setPosition(Vec2(
    front_size.width/2.0f,
    front_size.height/2.0f
));
lbl->setTextColor(Color4B::BLACK);
my_progress_timer->addChild(lbl);

足以做我想做的事。我不确定为什么以前没有这个工作。