17

Ok I have this code

@Override
public void render() {
    // do not update game world when paused
    if (!paused) {
        // Update game world by the time that has passed
        // since last render frame
        worldController.update(Gdx.graphics.getDeltaTime());
    }
    // Sets the clear screen color to: Cornflower Blue
    Gdx.gl.glClearColor(0x64/255.0f, 0x95/255.0f, 0xed/255.0f,
            0xff/255.0f);
    // Clears the screen
    Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
    // Render game world to screen
    worldRenderer.render();
}

And it draws a light blue background onto the screen. I am attempting to create a gradient that goes from a dark blue at the top, to a light blue towards the bottom. Is there a simple way to do this? I'm new to Libgdx, and OpenGL so i'm trying to learn from a book but I can't seem to find the answer to this one. I've heard of drawing a big square and having the vertices different colors, but I'm unsure of how to do this.

JonFavale
  • 255
  • 4
  • 12

3 Answers3

26

In libGDX, the ShapeRenderer object contains a drawRect() method that takes arguments for its position and size as well as four colors. Those colors are converted to a 4-corners gradient. If you want a vertical gradient, just make the top corners one color and the bottom corners another color. Something like this:

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

From the API for ShapeRenderer:

The 4 color parameters specify the color for the bottom left, bottom right, top right and top left corner of the rectangle, allowing you to create gradients.

Kevin Workman
  • 41,537
  • 9
  • 68
  • 107
  • I tried and got a black background, as if it wasn't drawing anything. What did I do wrong here? ShapeRenderer shapeRenderer = new ShapeRenderer(); shapeRenderer.begin(ShapeType.Filled); shapeRenderer.rect(0, 0, Constants.VIEWPORT_WIDTH, Constants.VIEWPORT_HEIGHT, Color.BLUE, Color.BLUE, Color.CYAN, Color.CYAN); shapeRenderer.end(); – JonFavale Jan 02 '14 at 19:01
  • 1
    Nevermind, turns out I used the width and height of the game world instead of the camera. Silly me. Thank you for the help! – JonFavale Jan 02 '14 at 19:07
  • As of today, this is outdated. – Fran Marzoa Oct 04 '16 at 18:52
  • @Fran Care to give any more information about that? Better yet, feel free to provide your own answer with an updated solution. – Kevin Workman Oct 04 '16 at 18:53
  • Sure, I'll do. I was just looking for answers and I didn't found it yet, that's why I just stated it was outdated. The problem is that shapeRenderer.filledRect doesn't exist anymore in late versions of libGDX, you ought to use shapeRenderer.rect instead having set ShapeType.Filled before. I'm going to put it in an answer, as you suggest. – Fran Marzoa Oct 05 '16 at 07:31
  • 3
    Note that in more recent versions of libgdx, `filledRect()` is now just `rect()`. – Code-Apprentice Nov 05 '16 at 22:32
  • how can i do similar thing with a circle .Is there any way to do so? – Ayush Bansal May 10 '17 at 05:38
  • This answer should be updated because filledRect() is deprecated. – Gad Wissberg Sep 12 '19 at 12:03
13

It seems ShapeRenderer.filledRect method has been removed in late libGDX versions. Now the way to do this is as follows:

shapeRenderer.set(ShapeRenderer.ShapeType.Filled);
shapeRenderer.rect(
        x,
        y,
        width,
        height,
        Color.DARK_GRAY,
        Color.DARK_GRAY,
        Color.LIGHT_GRAY,
        Color.LIGHT_GRAY
);

The parameters for rect method work in the same way as those in filledRect used to do, like in Kevin Workman answer.

Morgoth
  • 4,935
  • 8
  • 40
  • 66
Fran Marzoa
  • 4,293
  • 1
  • 37
  • 53
0

There are some further details worth bearing in mind before comitting to ShapeRenderer. I for one will be sticking with stretching and tinting Texture.

private Color topCol = new Color(0xd0000000);
private Color btmCol = new Color(0xd0000000);

@Override
public void render(float delta) {
    ...
    batch.end(); //Must end your "regular" batch first.
    myRect.setColor(Color.YELLOW);  // Must be called, I don't see yellow, but nice to know.
    myRect.begin(ShapeRenderer.ShapeType.Filled); //Everyone else was saying call `set`.
    //Exception informed me I needed `begin`. Adding `set` after was a NOP.
    myRect.rect(
            10, 400,
            //WORLD_H - 300,  // WORLD_H assumed 1920. But ShapeRenderer uses actual pixels.
            420,
            300,
            btmCol, btmCol, topCol, topCol
    );
    myRect.end();

I was hoping to change transparency dynamically as player health declines. The btmCol and topCol had no effect on transparency, hence I'll stick to Textures. Translating pixel space is no biggie, but this is much more than the proferred single or double line above.

mid section of my rect, not wanting to show above and below.

John
  • 6,433
  • 7
  • 47
  • 82