ForgeLeaf Logo

Consent to our cookie policy 🍪

We use a privacy-friendly, cookie-free analytics tool (Umami). Some cookies are used for functionality only. You may check our Privacy Policy.
A game window showing a bunch of fruits flying around

Drawing Advanced Shapes with SimpleBatch in LibGDX 🎁

Bismillah.
Today, we’ll take a short detour from Forge and look at something written purely for LibGDX, a little helper library called SimpleBatch.

If you’ve used LibGDX for any length of time, you’ve probably hit this wall before:
you want to draw some simple lines, rectangles, or circles and render textures in the same frame, but mixing ShapeRenderer and SpriteBatch can be a headache.
You either end up flushing batches too often or introducing z-order and blending issues.

That’s where SimpleBatch comes in.

👉 GitHub: https://github.com/ForgeLeaf/simple-batch-gdx


What is SimpleBatch? ⚙️

SimpleBatch is a drop-in shape renderer for LibGDX that lets you draw outlines, dashed shapes, circles, and lines all while staying inside a single batch.

It’s implemented as a thin wrapper around LibGDX’s Batch and uses the same shader system under the hood.
That means you can mix it directly with your existing sprite rendering, fonts, or UI.

The repository is split into two modules:

  • :library contains the main SimpleBatch source
  • :example is a minimal LibGDX example project demonstrating how to use it

If you just want to play with it, clone the repo and run:

./gradlew :example:run

You’ll get a small demo window showing rectangles, dashed outlines, and lines all drawn through SimpleBatch.


Getting Started 🧱

Create a new instance in your render() setup:

SimpleBatch batch = SimpleBatch.create();

or, if you want to control the buffer size or shader:

SimpleBatch batch = SimpleBatch.create(1000, myShader);

You use it just like a SpriteBatch:

batch.begin();
// draw shapes and textures here
batch.end();

If you ever need to pass it to something that expects a Batch (like BitmapFont or Stage), you can wrap it easily:

Batch compat = SimpleBatch.shim(batch);
font.draw(compat, "Hello LibGDX!", 100, 100);

Drawing Basic Shapes ✏️

Rectangle

batch.rectangle(100, 100, 200, 120, 2f, Color.RED);

Draws a red rectangle outline with 2px stroke width.


Filled Rectangle

batch.fill(100, 100, 200, 120, Color.CYAN);

Draws a solid cyan rectangle.


Dashed Rectangle

batch.dashRectangle(new Rectangle(50, 50, 150, 100), 2f, 16, 4f, Color.YELLOW);

Great for selection boxes, borders, or pulsing outlines.


Line & Dashed Line

batch.line(50, 50, 250, 50, Color.WHITE);
batch.dashLine(50, 70, 250, 70, 2f, 10, 4f, Color.ORANGE);

You can also blend two colors smoothly:

batch.line(50, 90, 250, 90, Color.BLUE, Color.PINK, 1.5f);

Circle & Dashed Circle

batch.circle(200, 200, 50, 2f, Color.LIME);
batch.dashCircle(400, 200, 50, 2f, 10, Color.CORAL);

Spikes 🌟

A fun one, generates radial spikes or bursts:

batch.spikes(300, 300, 60, 80, 16, 2f, Color.GOLD);

Perfect for effects, highlights, or energy bursts.


Mixing with Text & Sprites 🧩

Because SimpleBatch internally extends the LibGDX batch pipeline, you can easily draw fonts or textures alongside your shapes.

batch.begin();
batch.fill(50, 50, 200, 100, Color.SKY);
font.draw(SimpleBatch.shim(batch), "Overlay text", 70, 120);
batch.end();

You don’t have to flush or switch renderers — it’s all handled automatically.


The Example: Moving Fruit 🍎

In the :example submodule, you’ll find a small class called Fruit, which demonstrates how to animate and draw sprites using SimpleBatch.
Each fruit rotates, scales up and down, and wraps around the screen edges.

public void update(float delta, float worldWidth) {
    rotation += delta * multiplier * speed * 360f;
    scale += delta * multiplier * speed;
    if (scale < 1f || scale > 2f)
        multiplier = -multiplier;

    position.x += (left ? -1 : 1) * delta * speed;

    float halfWidth = width * 0.5f;
    if (position.x + halfWidth < 0)
        position.x = worldWidth + halfWidth;
    else if (position.x - halfWidth > worldWidth)
        position.x = -halfWidth;
}

This keeps the motion seamless, fruits reappear from the other side rather than popping back in.


Why Use SimpleBatch? 💡

  • No need for separate shape and sprite renderers
  • Simple API for outlines, dashed shapes, gradients, and fills
  • Fully batched, that means no extra flushes!
  • Compatible with any LibGDX shader or camera
  • Perfect for in-game overlays, editors, or debug visuals

Wrapping Up 🎬

SimpleBatch is a small utility library built to make everyday shape rendering in LibGDX just work.
It’s lightweight, extendable, and designed for real-world use in games, tools, or prototypes.

👉 Repository: https://github.com/ForgeLeaf/simple-batch-gdx

  • Library code: :library
  • Example project: :example
A game window showing a bunch of fruits flying around

Give us some feedback!

Thanks for reading our article. Could you please consider giving us some constructive, anonymous feedback?

Related articles

Working with ECS in LibGDX 🤩

Bismillah, dear readers!I hope you enjoyed the long weekend and managed to recharge. Today we’ll explore building a simple game using simple‑world‑gdx (my lightweight ECS for LibGDX), together with simple‑batch‑gdx…
Read more

Forge Framework

Forge is our free and open source game framework for the GoLang programming language. It is feature-rich and constantly improved. We designed Forge to be performant and simple for beginner, its power lies within its ecosystem and community. Forge is lightweight in nature and can be easily extended to fit most of your needs. Write you game logic in your way and let the framework handle compatibility.
Community

Connect with our community

ForgeLeaf Logo
Join the ForgeLeaf community — follow updates, contribute, and grow together.

Subscribe to our Newsletter

Stay Updated on the Latest Dev Insights. Join our mailing list to receive new articles, tutorials, and project updates.
ForgeLeaf Logo
Made with ❤️ in 🇩🇪
Follow us on social media
Subscribe to our Newsletter
© 2025 ForgeLeaf Studio