UI loading bar not working with spritesheet

Has anyone been successful in getting a UI loading bar to work when you are using a image from your sprite sheet ? before I started using the sprite sheet it worked fine, now with the sprite sheet it shows the %100 of the bar the whole time

How are you creating the ui::LoadingBar? Did you follow the code path in the debugger to see if it’s loading the texture properly?

1 Like
bool LevelOne::init()
{

// 1. super init first
if ( !Scene::initWithPhysics() )
{
    return false;
}

loadingBar = ui::LoadingBar::create("loadingbar.png", cocos2d::ui::Widget::TextureResType::PLIST);
loadingBar->setPosition( Vec2(visibleSize.width / 2, visibleSize.height / 2));
loadingBar->setPercent(0);
loadingBar->setVisible(false);
this->addChild(loadingBar, 1000);

loadingBarOutline = Sprite::createWithSpriteFrameName("loadingbaroutline.png");
loadingBarOutline->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2));
loadingBarOutline->setVisible(false);
this->addChild(loadingBarOutline);

loadLabel = Label::createWithTTF("Loading...", "fonts/Marker Felt.ttf", 150);
loadLabel->setColor(Color3B::WHITE);
loadLabel->enableOutline(Color4B::BLACK, 5);
loadLabel->setPosition( Vec2(visibleSize.width / 2, visibleSize.height / 2 + (loadLabel->getBoundingBox().size.height)));
loadLabel->setVisible(false);
this->addChild(loadLabel, 1005);

this->scheduleUpdate();

return true;

}

then in game over I call this method

void LevelOne::loadBar(float dt){

if(loadingBar->getPercent() == 0)
{
    loadingBar->setPercent(50);
    
} else if(loadingBar->getPercent() == 50)
{
    loadingBar->setPercent(100);
   
}else if(loadingBar->getPercent() == 100) {
 
    AdHelper::showInterstitialAd();
    loadingBar->setVisible(false);
    loadingBarOutline->setVisible(false);
    loadLabel->setVisible(false);
    gameEnded();
    
}
}

It was working perfectly fine before I created it with the sprite sheet, I didn’t see anything in the debugger, but the loading bar is showing but it shows at %100 the whole time, when its suppose to start at 0% then gradually go up to %100 not sure if this is a known problem with spritesheets for ui loading bar

That just brings up more questions than answers.

What is the purpose of the “float dt”? Where are you calling the loadBar() method from, and how are you calling it? Are you calling it in some kind of update() method?

At the moment you’re assuming that the sprite sheet is the issue, but you haven’t said anything about checking the value of the bar itself to verify that it contains a valid value. Have you actually checked to see if the value of getPercent() is correct all the time? Are you sure it’s not always 100%?

1 Like

I can’t remember why I had to put the float dt parameter but I remember it wasn’t working without it I call it on onContactBegin because thats when they get game over. I thought maybe it was the sprite sheet since everything was working fine before i added it. It even takes a few seconds like to load like it normally would but instead of progressing the bar is at %100 the whole time

and I set the value to 0 percent in my init method

bool LevelOne::onContactBegin(cocos2d::PhysicsContact &contact)
{
  PhysicsBody *a = contact.getShapeA()->getBody();
  PhysicsBody *b = contact.getShapeB()->getBody();

if((BALL_COLLISION_BITMASK == a->getCollisionBitmask() && OBSTACLE_COLLISION_BITMASK == b->getCollisionBitmask()) || (BALL_COLLISION_BITMASK == b->getCollisionBitmask() && OBSTACLE_COLLISION_BITMASK == a->getCollisionBitmask()))
{


        
    loadingBar->setVisible(true);
    loadingBarOutline->setVisible(true);
    loadLabel->setVisible(true);
        
    this->schedule(schedule_selector(LevelOne::loadBar), 1.0f, 2, 0);
    
}

return true;
}

You really need a better way to update the loading bar, because what you’ve done is not quite right.

Firstly, let’s look at the schedule() method:

void schedule(SEL_SCHEDULE selector, float interval, unsigned int repeat, float delay);

You’re passing interval = 1, repeat = 2, delay = 0 to it.

Now, take a step back, and think about how it is going to work.

First call:

if(loadingBar->getPercent() == 0)
{
    loadingBar->setPercent(50);
}

Now the 2nd call:
Loading bar is now 50%, now instantly (0 delay remember), it’s going to call it a again, and this happens:

if(loadingBar->getPercent() == 50)
{
    loadingBar->setPercent(100);
}

No more calls to it, since it’s already on 100%, and you only scheduled it to repeat 2 times.

As I mentioned earlier, you need to check the value in it. Either use a debugger and put breakpoints on the
setPercent() calls, or put CCLOG() calls in each of the if conditional blocks to see if they’re getting called.

I can’t quite understand how this code was ever working to begin with.

2 Likes

it gets called once and then repeats twice after that, so in total its 3 times that its getting called. for now I had to switch back to normal .png so it could work but I will try adding the image to my sprite sheet again tomorrow and do more debugging. also I couldn’t find another way to make the loading bar gradually increase thats why I went with the schedule_selector

Did you look into Actions?

auto actionFloat = ActionFloat::create(2.f, 0, 100, [this](float value) {
    loadingBar->setPercent(value);
});

auto sequence = Sequence::create(actionFloat, CallFunc::create([this]() {
    AdHelper::showInterstitialAd();
    loadingBar->setVisible(false);
    loadingBarOutline->setVisible(false);
    loadLabel->setVisible(false);
    gameEnded();
}), nullptr);

loadingBar->setAction(sequence);

The cpp-test demo app has everything you need, so stating that you can’t find another way is a little perplexing. It’s literally showcased in that demo under the Actions - Basic section.

3 Likes

I will try this out tomorrow and see if it works , I didn’t know there was code for a loading bar demo , someone else had pointed me to the scheduler way of doing it

There is a doc here: https://docs.cocos2d-x.org/cocos2d-x/en/ui_components/loading_bar.html?h=loading

and cpp-tests has at least 1 working example.

1 Like

@IzzyJM Yes, it will not work from spritesheet for many UI elements.
We keep those images out side of spritesheets.
Never had time to dig into sourcecode for this bug.
I think we need to create bug for this to keep track.

2 Likes

Edit: Sorry guys, I was thinking of the wrong thing when I posted initially regarding the trim and rotate (it’s the cocos2d particle code that doesn’t support them). I just tested it out with both trim and rotate enabled on textures in a sprite sheet, and ui::LoadingBar worked perfectly fine. It started from 0, and went all the way to 100% without issue.

This is the test:

loadingBar = ui::LoadingBar::create("Bar.png", ui::Widget::TextureResType::PLIST, 0);
loadingBar->setGlobalZOrder(1000);
loadingBar->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2));
this->addChild(loadingBar);

auto action = ActionFloat::create(10, 0, 100, [this](float value)
{
    loadingBar->setPercent(value);
});
loadingBar->runAction(action);
3 Likes

wow, never knew this.
But i think this 2 option is must for spritesheet o/w we cannot take max advantage of spritesheets.

1 Like

did you use polygon out line for trimmode ?

No, all of the sprite sheets I’m using are created with the algorithm set to MaxRects, and I can’t quite recall the reason for that at the moment.

1 Like