JasperTack
JasperTack

Reputation: 4457

Drawing subset of a gradient in libgdx

I know this question has been accessed before (like here), but I was wondering how to do the following. In my game, I have a scrolling background. There is for example a blue sky that is light blue at the bottom and gets darker the higher you go. This is not really possible with the suggested solution:

shapeRenderer.filledRect(x, y, width, height, 
                         lightBlue, lightBlue, darkBlue, darkBlue);

since you can only give the colors that really will be shown. I would like to have a gradientPaint with at the top darkblue and the bottom lightblue that stretches out over for example 500 pixels. This, while I only draw only 200 pixels of it. With this, the color would still get darker when the background scrolls. Does anybody know how to do this with libgdx?

Upvotes: 0

Views: 266

Answers (1)

P.T.
P.T.

Reputation: 25177

What you want is to see a smaller (say 200 pixel) window onto a larger (say 500 pixel) gradient. To do that you just need to compute the colors of four corners colors based on the location of your window in the overall gradient, and then draw just that. (So don't think about drawing the entire background, but about figuring out how to draw just the part that you need.)

Since you're just moving smoothly between the two colors (between 0 and 500), you're doing a "linear interpolation" (that is a straight-line estimation) between the colors based on where the Window is. Libgdx supports this via the lerp() methods on Color.

Assuming the window is travelling along the Y axis, something like this should give what you want:

Color baseColor = lightBlue;
Color topColor = darkBlue;

int skyHeight = 500;
int windowHeight = 200;
int windowLocation = ...; // something betweeen 0 and skyHeight - windowHeight;
Color windowBottomColor = baseColor.copy().lerp(topColor, windowLocation / skyHeight);
Color windowTopColor = baseColor.copy().lerp(topColor, (windowLocation + windowHeight) / skyHeight);

Now windowBottomColor and windowTopColor should be suitable for calling filledRect:

shapeRenderer.filledRect(x, y, width, height, 
                         windowBottomColor, windowBottomColor, windowTopColor, windowTopColor);

Note that the "copy()" calls create a new Color object for each invocation, so you might want to optimize that to avoid the allocation.

Disclaimer: I haven't tried this code, so it probably has some stupid bugs in it, but hopefully it gives you the right idea.

Upvotes: 2

Related Questions