Custom progress bar effect

I am making a custom progress bar, which is a droplet, the background is little transparent and as the game loads it gets filled…

so as it progress i want it to be filled. So how can i get such effect?

You can achieve such an effect with a clipping node and an attached sprite stencil.

Your light area is a clipping node, with the drop sprite added as a sprite stencil.
Your dark area could be a rectangle, which is attached to the clipping node and moved upwards to act as a filling gauge.

2 Likes

You can do it by using one png and without clipping node, if you want to make it simple.
Create 2 sprite with same loading png.

        loadSpriteAlpha = Sprite::create("loading.png");
	loadSpriteAlpha->setPosition(Vec2(viewSize.width / 2, viewSize.height / 2));
	loadSpriteAlpha->setAnchorPoint(Vec2(0.5, 1));
	loadSpriteAlpha->setOpacity(55);

	loadSprite = Sprite::create("loading.png");
	loadSprite->setPosition(Vec2(viewSize.width / 2, viewSize.height / 2));
	loadSprite->setAnchorPoint(Vec2(0.5, 1));
	loadSprite->setTextureRect(Rect(loadSpriteAlpha->getTextureRect().getMinX(), 
                                        loadSpriteAlpha->getTextureRect().getMinY(), 
                                        loadSpriteAlpha->getTextureRect().getMaxX(), 
                                        0));

and take one loading variable and use setTextureRect to adjust clipping.

loadSprite->setTextureRect(Rect(loadSpriteAlpha->getTextureRect().getMinX(), 
                                        loadSpriteAlpha->getTextureRect().getMinY(), 
                                        loadSpriteAlpha->getTextureRect().getMaxX(), 
                                        .... ));
1 Like

If this is more simple than using a clipping node is highly arguable and not flexible at all. E.g., a 45 degree filling needs much more work. Using a clipping node, it’s just a simple rotation.
The code is way more complicated in my eyes. Not even to mention that it’s much more code.

Performance can also be very different: using a scissor test vs. manipulating the texture rectangle by hand.

+1 for using a stencil for the tear shape and attach a standard progress bar as a child, or just draw two different colored rectangles over each other.

@iQD, @smitpatel88, @mannewalis thanks for the solution…

But @iQD can you share some code snippet for reference, would love to execute both the techniques and understand in detail…

// create the sprite used as a stencil
auto dropletSprite = Sprite::create();
dropletSprite->setTexture("droplet.png");

// create the clipping node
auto dropletClipper = ClippingNode::create();
dropletClipper->setPosition(Point(1500.0f, 500.0f));

// attach the stencil to the clipping node and add it as a child,
// so the droplet itself can act as the background layer
dropletClipper->setStencil(dropletSprite);
dropletClipper->addChild(dropletSprite);

// create the sprite used for the gauge
// it can be the droplet form itself, or a rectangle
// but needs the same width as the stencil
auto gaugeSprite = Sprite::create();
gaugeSprite->setTexture("gauge.png");

// create a progress timer, working on the gauge sprite
auto progressTimer = ProgressTimer::create(gaugeSprite);

// set the midpoint to the center bottom, as the gauge is filling up from the bottom
// to the top
progressTimer->setMidpoint(Vec2(0.5f, 0.0f));

// the gauge is working linear
progressTimer->setType(ProgressTimer::Type::BAR);

// the progress timer is only working on the y axis of the gauge
// the x axis stays at 100 % all the time
progressTimer->setBarChangeRate(Vec2(0.0f, 1.0f));

// set the filling of the gauge in percent; from 0-100%
progressTimer->setPercentage(15.0f);

// add the progress timer as a child to the clipper, so the gauge will follow the
// droplet form
dropletClipper->addChild(progressTimer);

// add the clipping node to the layer
addChild(dropletClipper, 1000, "dropletMagic");

// do some voodoo gauge filling fun
3 Likes

One different colored rectangle is enough, if you are using the stencil itself as the background layer :smile:

1 Like

@iQD even i use clipping node for that but as you already mention that so i gave different solution.
But i still think my solution is not that much code. :smile: (I used this in one of my game)

Thanks a lot guys…Really nice explanation of the methods…

1 Like