Tinting a tile in LibGDX

Alright, currently in my project I’m rendering a tile, then rendering another tile that overlays onto the first and sort of provides tile based lighting. The first tile is the texture, then the second tile just has a black texture with the alpha value changed so that it can make the first tile lighter or darker. This isn’t very efficient, however, because I have to render twice as many tiles for every tile space. The lighting in my game changes depending on the time of day, and the torches. So, is there anyway to tint the tiles texture using only one tile? I’m using LibGDX and my tiles are objects of the

Sprite

class. I’m not using shaders right now, but if I need to I can.
Thanks!

if you use sprite and you want only make your tile lighter or darker you can use the .setColor() of your tile.
this is an example :

sprite.setColor(sprite.getColor().r, sprite.getColor().g, sprite.getColor().b, value);

with this you can set the opacity of the tile without change the color of it.
I also think that if you add value to r,g and b channel you can change the darkness or lighter of your sprite, you can try.
I hope this can help :slight_smile:

Thank you! Lots ;D Ill try it out and report back!

That didn’t work…
This is my tile class:

package com.nishu.particaletest.entities;

import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.nishu.particaletest.GameScreen;

public class Tile extends Entity{
	
	private boolean isSolid, isLit;
	Texture tex;
	Sprite tile;
	float lightVal;
	
	public Tile(int x, int y, boolean isSolid, boolean isLit){
		super((x * GameScreen.scale) * 16, (y * GameScreen.scale) * 16);
		this.isSolid = isSolid;
		this.isLit = isLit;
		
		if(!isSolid)
			this.tex = new Texture("data/grass.png");
		else 
			this.tex = new Texture("data/stone.png");
		
		tile = new Sprite(tex);
		tile.setColor(0, 0.5f, 1, lightVal);
		tile.setPosition((x * GameScreen.scale) * 16, (y * GameScreen.scale) * 16);
	}
	
	public void render(){
		
	}
	
	public void update(){

	}

	public boolean isSolid() {
		return isSolid;
	}

	public void setSolid(boolean isSolid) {
		this.isSolid = isSolid;
	}

	public boolean isLit() {
		return isLit;
	}

	public void setLit(boolean isLit) {
		this.isLit = isLit;
	}

	public Texture getTex() {
		return tex;
	}

	public void setTex(Texture tex) {
		this.tex = tex;
	}

	public Sprite getTile() {
		return tile;
	}

	public void setTile(Sprite tile) {
		this.tile = tile;
	}

	public float getLightVal() {
		return lightVal;
	}

	public void setLightVal(float lightValue) {
		this.lightVal = lightValue;
	}

}

I set the color up in the constructor, and no matter how much I change the values, the colors of the textures do not change. Do I need to enable something for coloring to work?

your render method is empty, how do you render ?

I suppose you are actually rendering “tex” and not “tile”

Ah yes, sorry. This is just a test project, so my code is pretty messy, but here is how I render:

	@Override
	public void render(float delta) {
		Gdx.gl.glClearColor(0, 0, 0, 1);
		Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
		batch.begin();
		for (int x = 0; x < ParticaleGame.WIDTH / 16; x++){
			for(int y = 0; y < ParticaleGame.HEIGHT / 16; y++){
				batch.draw(tiles[x][y].getTex(), (float)tiles[x][y].getX(), (float)tiles[x][y].getY());
				tiles[x][y].setColor(0, 0, 0, 0.5f);
			}
		}
		batch.end();
	}

And yes, my names are slightly confusing, tile is the sprite object and tex is the texture object.

dont forget the getColor part.
The thing you do now is you draw it once with color, then you set the sprite color with no red green or blue elements in it. Meaning everything will be black.

Right, I know that was a test. But the texture is still the same color as before, its not black! I don’t understand why its not working :confused:

What is your setColor function in your entity class?

It just calls

tile.setColor(r, g, b, a)

Tile is an object of the Sprite class.

Bumping because I have another question. Won’t changing the tile’s RGB values change the actual look of the tile? I feel like the image would look very distorted in terms of color, but if I used an overlay and just changed the alpha value according to the time of day, it might look better. Of course, I have no idea since I can’t get the coloring code to work anyway. Any help would be appreciated!

“Changing” the tile’s RGB is like using a mask. It doesn’t write those changes to the file.

Right, I know. Its just somewhere I heard someone say directly changing the RGB values of a texture looks different than actually using a separate mask. While your here though, could you venture a guess as to why my tiles aren’t changing color?

When drawing a sprite, you should use the sprite.draw() method instead of the batch. I guess that this might be the reason why it is not getting tinted correctly.
You could set the color for the batch too if you want.

Ok, that just takes a SpriteBatch right? I’m confused though because on the LibGDX docs, they call batch.draw and change the color of sprites. Here’s why I found:

private Texture texture;
private TextureRegion region;
private Sprite sprite;
...
texture = new Texture(Gdx.files.internal("image.png"));
region = new TextureRegion(texture, 20, 20, 50, 50);
sprite = new Sprite(texture, 20, 20, 50, 50);
sprite.setPosition(100, 10);
sprite.setColor(0, 0, 1, 1);
...
batch.begin();
batch.setColor(1, 0, 0, 1);
batch.draw(texture, 10, 10);
batch.setColor(0, 1, 0, 1);
batch.draw(region, 50, 10);
sprite.draw(batch);
batch.end();

So, what’s the difference between my code?

THIS:


batch.setColor(1, 0, 0, 1);
batch.draw(texture, 10, 10);
batch.setColor(0, 1, 0, 1);

is what sprite.render does and it uses the color you have setted.

Sprite is a convenience class, either use it or not, but make up your mind :smiley:
meaning you call sprite.setColor, preferably only once, unless it changes every frame and then sprite.draw(batch)

That’s the code from the official docs :stuck_out_tongue: I only call sprite.setColor and batch.draw, I don’t see how that’s a bad thing to use both. Sprite.draw seems like it gives the same results as batch.draw, so why does it matter?

So, I was playing with my code, and I realized that the sprite only serves to render my texture. If I try to set the position of the sprite or rotate it or anything, it doesn’t work. When I call sprite.draw(batch) and assign the sprites into a grid, the sprites still only render at coords 0, 0. I specifically set sprite.set position so I have no idea why that’s not working. However, if I just draw the tiles like this:


for (int x = 0; x < width; x++){
//loop through other dimension
batch.draw(tiles[x][y].getTex(), tiles[x][y].getX(), tiles[x][y].getY());
}

It works fine and the tiles arrange into a grid. This is the first time I’ve used LibGDX, so I imagine this is a rookie mistake, but I really don’t understand why working with the sprites doesn’t work.

Well, I’ve discovered some more info. Every example code ive seen has a camera as well as a sprite. Do I need to have a camera to properly render a sprite? This doesn’t make sense, but I’m grasping at straws here.

guy… do you ever listen ? :smiley:

maybe you should look into the source code of sprite to understand whats happening

if you have a sprite
then do sprite.setcolor(bla)
and then batch.draw(sprite.getTex()
there will be no color change

same with rotation, position, what have you