LibGDX - draw a shape in middle of zIndex of a group - libgdx

I want to draw a filled circle in the middle of a group containing two images.
I've tried doing it with
#Override
public void draw(Batch batch, float parentAlpha) {
batch.end();
renderer.setProjectionMatrix(batch.getProjectionMatrix());
renderer.setTransformMatrix(batch.getTransformMatrix());
renderer.translate(getX(), getY(), 0);
renderer.begin(ShapeRenderer.ShapeType.Filled);
renderer.rotate(0, 0, 1, getRotation());
renderer.setColor(new Color(0xffd700ff));
renderer.circle((getWidth() / 2), (getHeight() / 2) , (getWidth() / 4));
renderer.end();
batch.begin();
super.draw(batch, parentAlpha);
}
The problem is, I want my first image drawn, then my circle, then a label on top of that. However, it seems I can't do this because I can either draw both image and label on top of the circle, or the circle on top of the other two.

Related

glow effect with ShapeRenderer (libgdx)

I read about glow/particle effecta with sprites, which are working well.
Is there a simple way to create the similar blur effect with simple shaperender functionality like circles ?
#Override
public void draw(Batch batch, float parentAlpha) {
super.draw(batch, parentAlpha);
batch.end();
shapeRenderer.begin(ShapeRenderer.ShapeType.Point);
shapeRenderer.setAutoShapeType(true);
drawCircle();
shapeRenderer.end();
batch.begin();
}
private void drawCircle() {
shapeRenderer.setColor(Color.WHITE);
shapeRenderer.set(ShapeRenderer.ShapeType.Filled);
// apply effect ??
shapeRenderer.circle(10,10,2);
}
You can't use textures with default ShapeRender.
There are several way to do this but the easiest is to use ShapeDrawer library. It adds some "ShapeRenderer like" capabilities to a SpriteBatch and more. see https://github.com/earlygrey/shapedrawer
Yes, you could create a "glow" effect, this could be achieved by drawing using decreasing alpha values past the boundaries.
Firstly, to define the glow-effect parameters, let's determine the maximum boundary of the glowing object, where the glow ends, as being auraSize for the size of the aura.
Next, we need to know the size of the solid portion of the object, the bit that doesn't glow, and let's call this objSize for the size of the object.
To draw this, we can use a simple for loop and some if statements:
private void drawCircle() {
shapeRenderer.set(ShapeRenderer.ShapeType.Filled);
//Draw circles upto the size of aura
for(int radius = 0; radius < auraSize; radius++) {
/*
* Checks if radius fits object size, sets colour to solid white if so
* Interpolates alpha value to 0 based on distance to aura covered by radius otherwise
*/
if(radius <= objSize) {
shapeRenderer.setColor(Color.WHITE);
} else {
shapeRenderer.setColor(new Color(1, 1, 1,
MathUtils.lerp(1, 0, (radius - objSize) / (auraSize / objSize))));
}
//Draws the circle at the current radius
shapeRenderer.circle(10, 10, radius);
}
}

Howto rotate a Sprite after resizing the Sprite with setBounds ? (LIBGDX)

I have a Bitmap (png) loaded into my Sprite with a specific size (200) and a Center at 100/100 for rotation:
Sprite round = loadSprite(200,200);
round.setPosition(x,y)
When Rotating round.setRotation() the Sprite rotates around the correct Center.
Now I would like to size the Sprite to a new Size (400,400) and still want to rotate around the Center (200/200):
round.setBounds(x,y,400,400)
rount.setCenter(200,200);
When rotating again, it is still rotating around the old Center 100/100.
How to do this corectly ?
setCenter(x, y) set the position of the Sprite so it is centered to this position:
/** Sets the position so that the sprite is centered on (x, y) */
public void setCenter(float x, float y){
...
}
You need the function setOrigin(originX, originY):
/** Sets the origin in relation to the sprite's position for scaling and rotation. */
public void setOrigin (float originX, float originY) {
...
}

shaperenderer rounded corner triangle

I would like to create a triangle shape with rounded corners. I can't use a sprite since the shape will change all the time so shaperenderer seems as a good option. I currently do:
shapeRenderer.setProjectionMatrix(camera.combined);
shapeRenderer.begin(ShapeType.Filled);
shapeRenderer.setColor(0.2f, 0f, 0f, 1f);
// shapeRenderer.filledTriangle(50f, 50f, 55f, 55f, 60f, 60f);
shapeRenderer.triangle(0, 0, 5f, 5f, 5f, 4f);
shapeRenderer.end();
which produce something like:
but I need something like:
Any ideas?
Either use an image that you draw from Photoshop with Sprite and SpriteBatch, or a Stencil to cut out the edges.

Libgdx blending contrast issue in render();

In a Libgdx 1.x Stage, my goal is to apply a dark semi transparent mask on my screen except an area that should display the original screen.
My global render method:
public void render() {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.setShader(null);
update();
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
batch.begin();
darkener.draw(batch, 0.7f);
spotlight.draw(batch, 1f);
batch.end();
}
Both instances of objects Darkener and Spotlight are Sprites made from a pure white 4x4 texture:
spotlight = new Sprite(new Texture(Gdx.files.internal("data/ui/whitepixel.png")));
darkener = new Sprite(new Texture(Gdx.files.internal("data/ui/whitepixel.png")));
I give my Darkener object the size of the screen, and my Spotlight object the size of the area I want not to be darkened.
Here is the draw method of my object darkener:
public void draw(Batch batch, float alpha) {
darkener.draw(batch, alpha);
}
And the draw method of my Spotlight object:
public void draw(Batch batch, float alpha) {
batch.setBlendFunction(GL20.GL_DST_COLOR, GL20.GL_SRC_ALPHA);
spotlight.draw(batch, alpha);
batch.setBlendFunction(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
}
My problem is about blending:
With the parameters:
darkener.draw(batch, 0.7f);
spotlight.draw(batch, 1f);
The preserved (spotlight) area is darker than the original.
With the parameters:
darkener.draw(batch, 0.3f);
spotlight.draw(batch, 1f);
The preserved (spotlight) area is brighter (saturated) than the original.
With the paremeters:
darkener.draw(batch, 0.5f);
spotlight.draw(batch, 1f);
The preserved (spotlight) area is exactly like the original (so, as I want it). The problem is that I want to be able to set different values for my Darkener either < 0.5f or > 0.5f.
What I am doing wrong?
The blend function you're using for the spotlight takes the current pixel brightness and multiplies it by (1+alpha).
So if you darken to 0.7 of brightness (using a darkener alpha of 0.3), you want the spotlight to multiply the brightness by 1/0.7 = 1.429 so you should use a spotlight alpha of 0.429. So:
spotlightAlpha = 1/(1-darkenerAlpha) - 1; //assuming darkener RGB is black
The problem is if you darken to less than 0.5 brightness (darkner alpha > 0.5), because alpha cannot be greater than 1. You would have to run the spotlight with alpha 1 repeatedly until the brightness is above 0.5 and then one more time with the appropriate value.
You will lose color precision the darker you go so this method may not be suitable. Might want to consider drawing 8 dark boxes instead. And if you want the spotlight to be non-rectangular you can make its sprite inverted to fill in the middle rectangle.

Textures overlapping

I am new in LibGDX and I would like to know how to make one texture appear in front of the other, because lets say we have 2 textures(t1 and t2) with shape of a square. And when they overlap, I see the color of t1 but I would like to see the color of t2? Is there any way that I can make some kind of priorities or?
Just draw your texture in render() function in needed order. Last drawn texture will be on the first visible layer. Example: (if the texture have the same size, you will see only second one):
#Override
public void render(float delta) {
spriteBatch.begin();
Gdx.gl.glClearColor(0.5f, 0.5f, 0.5f, 1f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
spriteBatch.draw(YOUR_TEXTURE_1, 0, 0);
spriteBatch.draw(YOUR_TEXTURE_2, 0, 0);
spriteBatch.end();
}