Looking for a good way to apply a night effect over a game tile?

I want to implement night\day cycles, I was wondering if anyone knows of an optimal way to do this through Java2D. Ideally, I’d need to overlay from dark-blue to white over individual tiles (each image for a tile is stored as an Image).

I haven’t been able to think of any good ways of doing this. Thanks.

If the ambient light is evenly applied over all tiles, could you just create a BufferedImage the size of your screen, set it to the desired alpha & colour, and draw it after you draw your tiles???

I had to do something VERY similar just yesterday!

This should give you an idea. I’m writing this at work so don’t expect this to go perfectly.


int alpha = 0;

public static void render(Graphics g) {
    for (int x = 0; x < GameClass.display.width; x += YourImage.getWidth()) {
        for (int y = 0; y < GameClass.display.height; y += YourImage.getHeight()) {
            g.drawImage(YourImage, x, y);
        }
    }

    g.setColor(new Color(0, 0, 0, alpha));
    g.fillRect(0, 0, GameClass.display.width, GameClass.display.height);

    alpha++;
}

This basically tiles an image and draws an alpha mask over it that gets darker as the game ticks.

For a day/night cycle you should just set the alpha to go up when it’s night time and for it to go down when it’s day time.

Actually, I can’t believe I didn’t think of something like that lol.

Okay, so I think I’ll do something like that but on a per-tile basis, than I can scan a radius of the tile for light-sources and decay that light sources colour’s alpha effect on the tile as it is further away.

Thanks for the responses.

That didn’t work (for the reason I feared it would not.) The drawpolygon routine in Java2D’s Graphics2D object is way too slow. I know that the overhead is caused by that routine because if I leave my algorithm in and comment out the call to draw polygon - the CPU usage drops dramatically.

The resulting effect is some-what desirable though (I could hack and tweek off of this - but it would need to perform much quicker…):

edit
I’m going to try and layer ovals - this would produce a nicer effect I think - and it would definitely reduce overhead.

Well darn.

How does it work when you aren’t doing it per-tile?

I haven’t tried - but I imagine that if I overlayed the entire map it would work fine (and to intend on doing that for ambient light sources)

For point light-sources I think I am going to try layering ovals of increasing radius at the particular point after rendering the tiles - we’ll see how that works out - it should be much quicker and I think it’d be smoother but I’m not too sure. I’ll have to see.

What if you draw a sprite like this directly on top with alpha?

That’s a good idea, and it would probably work for baking in a lighting effect - but if I want dynamic lighting - like a moving light source - I would need to find some way to optimally generate the light maps on the fly.

What I was thinking is to have a low-priority background thread do it and present a new light map at intervals of half a second or so - that would probably work without much a of a performance hit, I’ll have to toy around a bit with it.

Oh, I just use a recursion:


public void lightSource(int x, int y, float brightness) {
		if (tiles[x][y].getBrightness() >= brightness && brightness < 1)
			return;
		tiles[x][y].setBrightness(brightness);
		brightness -= .2f;

		if (x != 0)
			lightSource(x - 1, y, brightness);
		if (x != getGenTilemap().getWidthInTiles() - 1)
			lightSource(x + 1, y, brightness);
		if (y != 0)
			lightSource(x, y - 1, brightness);
		if (y != getGenTilemap().getHeightInTiles() - 1)
			lightSource(x, y + 1, brightness);
	}

I cant remember who to credit, but I got this on these forums.

He knows how to set the brightness. It’s drawing it and getting it to render smoothly that he’s having a problem with.

I managed to get a solid frame-rate with dynamic rendering using a series of Java2D composition hacks - there are a few bugs I need to work out (and I need to turn this hacky implementation into a proper implementation) but it works well, it looks as I expected it would and it performs relatively quickly:

If you are truly wanting a day/night cycle, shouldn’t you be setting the background color/image as well? :stuck_out_tongue:


EDIT

I’m an idiot, I just figured out you were talking about the black border. Yeah - well normally that wouldn’t be visible (I am working with small maps because they’re easier to debug etc & my map editor isn’t exactly the most stable thing in the world.

The way I do it for anyone interested:
What happens is the ambient colour is layered over the screen (day\night shade) - the point-light sources have an area they’re going to apply their lighting effect too as well and I can’t cover those areas (otherwise I lose significant quality with my lighting.) So I use two Area objects, one covers the entire area of my map, the other I add my light source’s effect area to - then I subtract my light source area from my world map area and draw the ambient light using the world map area.

Then I fill in the spaces I didn’t apply the overlay to with the lighting effects by calling the respective pointlight’s rendering routine (which is passed an ambient colour to lerp with).

This system allows me to implement all sorts of lights too (like, i.e directional lights)