RadialGradientPaint problem

Hi guys,

I’ve been banging my head against this particular brick wall for a couple of days now… I’m trying to create a circle that fills itself from transparent at the centre to black at the edges using RadialGradientPaint but I just can’t get it to work!

Here’s what I’m using right now:

RadialGradientPaint whiteToBlack = new RadialGradientPaint(
	50,  //  x centre
	50,  //  y centre
	50,  //  radius of fill
	new float[] { 0.0f, 1.0f },   //  start position of each color
	new Color[] { new Color(1f, 1f, 1f, 0f), Color.BLACK }, //  the colors
	CycleMethod.NO_CYCLE
);

lightG.setPaint( whiteToBlack );

//  draw in the centre of the screen, a 100x100 pixel oval
lightG.fillOval(this.width/2-50, this.height/2-50, 100, 100);

This is what it draws:

It seems to be completely ignoring the first color, I’ve tested with different colors and whichever is the second color I use, that’s the one that shows up.

Totally confused by it! ???

Any help gratefully received :slight_smile:

RadialGradientPaint takes a bit of getting used to. Assuming that the code you posted is in your paint method, try changing it to the following:


RadialGradientPaint whiteToBlack = new RadialGradientPaint(
    this.width/2,  //  x centre
    this.height/2,  //  y centre
    50,  //  radius of fill
    new float[] { 0.0f, 1.0f },   //  start position of each color
    new Color[] { new Color(1f, 1f, 1f, 0f), Color.BLACK }, //  the colors
    CycleMethod.NO_CYCLE
);

lightG.setPaint( whiteToBlack );

//  draw in the centre of the screen, a 100x100 pixel oval
lightG.fillOval(this.width/2-50, this.height/2-50, 100, 100);

The first two parameters to radial gradient paint define an absolute position of where your start color appears in your viewport, it’s not relative to the position of the shape being filled. The implication is that you’ll have to recompute the x and y center of the gradient whenever your game’s resolution changes, but that shouldn’t be too difficult to work around.

One other thing. Assuming you’re going for a 2D lighting effect around your character, use fillRect(…) to fill the entire viewport instead of fillOval(…). You’ll still get a nice, round, gradient cutout at the center of the viewport with the rest being filled by your end color. If you’re going for a different effect, you can disregard the last part. :point:

Hope this helps.

Well, well, well. It was the “centre point is are relative to the viewport” that had me. Not seen that written anywhere, I thought it would be relative to the shape I was drawing.

As it goes, it’s for my lighting effect - each entity that creates light has this transparent image drawn on top of it with black all around. At least that’s the plan :slight_smile:

If you’re going to have multiple light sources, then you may want to consider creating a RGBA buffered image that’s the same size as your view and initially filled with black. When you want to add a light source, paint it onto the buffered image using your gradient paint. Once you’ve finished drawing your lights, apply the buffered image to the whole scene. As a bonus, you can change the alpha/color of the buffered image to achieve “time of day” lighting type effects. If that’s already the direction you were headed in, then carry on. It’s a pretty simple yet effective way to approach lighting for 2D.

Cheers. :slight_smile:

Yep that’s exacty the direction I’m taking, thanks :slight_smile:

Already got the background done - looping over light generating entities and creating The circle around them. The only part I was missing was the transparency.

Now all I need to do is make it take less than 25ms per frame to draw them all :frowning:

Baking things into BufferedImages is how I do J2D when I need relative speed.

You guys just saved my sanity - thank you so much!