Pular para o conteúdo

libGDX Cheat Sheet

Overview

libGDX is a free, open-source Java game development framework that provides a unified API for writing games that run on desktop (Windows, macOS, Linux), Android, iOS, and HTML5/WebGL. It offers a comprehensive set of tools including 2D and 3D rendering via OpenGL ES, a 2D physics engine (Box2D), audio playback, input handling, file I/O, and asset management. The framework follows a write-once approach where game logic is shared across platforms, with platform-specific launchers handling initialization.

libGDX uses a lightweight design philosophy, giving developers full control over the game loop and rendering pipeline rather than imposing a specific architecture. It supports scene graphs via Scene2D, tile map rendering, sprite batching, bitmap font rendering, particle effects, and shader programming. The framework is battle-tested in thousands of published games on Google Play, Steam, and iOS App Store, and its active community maintains numerous extensions for networking, AI, and UI components.

Installation

# Prerequisites: JDK 11+ and an IDE (IntelliJ IDEA or Eclipse)

# Option 1: Use the official project generator
# Visit https://libgdx.com/wiki/start/project-generation
# Download and run gdx-liftoff.jar
java -jar gdx-liftoff.jar

# Option 2: Use gdx-liftoff CLI
git clone https://github.com/libgdx/gdx-liftoff.git
cd gdx-liftoff
./gradlew run

# Project generator settings:
# - Project name, package, main class
# - Platforms: Desktop, Android, iOS, HTML
# - Extensions: Box2D, Freetype, Controllers, etc.

# After generation, build the project:
cd MyGame
./gradlew desktop:run      # Run desktop version
./gradlew android:run      # Run on Android device
./gradlew html:dist        # Build HTML5 version
./gradlew ios:launchIPhoneSimulator  # Run iOS simulator

Project Structure

MyGame/
├── build.gradle                 # Root build file
├── settings.gradle
├── core/                        # Shared game code
│   └── src/main/java/com/mygame/
│       ├── MyGame.java          # Main game class
│       ├── screens/
│       │   ├── GameScreen.java
│       │   └── MenuScreen.java
│       ├── entities/
│       └── utils/
├── desktop/                     # Desktop launcher
│   └── src/main/java/.../DesktopLauncher.java
├── android/                     # Android launcher
│   └── src/main/java/.../AndroidLauncher.java
├── html/                        # HTML5/GWT launcher
│   └── src/main/java/.../HtmlLauncher.java
├── ios/                         # iOS launcher
│   └── src/main/java/.../IOSLauncher.java
└── assets/                      # Shared game assets
    ├── images/
    ├── audio/
    ├── fonts/
    └── maps/

Core Game Class

package com.mygame;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.Texture;

public class MyGame extends ApplicationAdapter {
    SpriteBatch batch;
    Texture img;

    @Override
    public void create() {
        batch = new SpriteBatch();
        img = new Texture("badlogic.jpg");
    }

    @Override
    public void render() {
        Gdx.gl.glClearColor(0, 0, 0, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        
        batch.begin();
        batch.draw(img, 0, 0);
        batch.end();
    }

    @Override
    public void dispose() {
        batch.dispose();
        img.dispose();
    }
}

Screen Management

// Using Game class with screens
public class MyGame extends Game {
    public SpriteBatch batch;
    public AssetManager assets;

    @Override
    public void create() {
        batch = new SpriteBatch();
        assets = new AssetManager();
        setScreen(new MenuScreen(this));
    }

    @Override
    public void dispose() {
        batch.dispose();
        assets.dispose();
    }
}

public class GameScreen implements Screen {
    private final MyGame game;
    private OrthographicCamera camera;

    public GameScreen(MyGame game) {
        this.game = game;
        camera = new OrthographicCamera();
        camera.setToOrtho(false, 800, 480);
    }

    @Override
    public void render(float delta) {
        Gdx.gl.glClearColor(0, 0, 0.2f, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        camera.update();
        game.batch.setProjectionMatrix(camera.combined);

        game.batch.begin();
        // Draw game objects
        game.batch.end();
    }

    @Override public void show() { }
    @Override public void resize(int width, int height) { }
    @Override public void pause() { }
    @Override public void resume() { }
    @Override public void hide() { }
    @Override public void dispose() { }
}

Rendering

// SpriteBatch for 2D rendering
SpriteBatch batch = new SpriteBatch();
Texture texture = new Texture(Gdx.files.internal("player.png"));
TextureRegion region = new TextureRegion(texture, 0, 0, 32, 32);
Sprite sprite = new Sprite(texture);

batch.begin();
// Draw texture at position
batch.draw(texture, x, y);
// Draw with size
batch.draw(texture, x, y, width, height);
// Draw region
batch.draw(region, x, y);
// Draw sprite (with rotation/scale)
sprite.setPosition(100, 200);
sprite.setRotation(45);
sprite.setScale(2.0f);
sprite.draw(batch);
batch.end();

// ShapeRenderer for primitives
ShapeRenderer shapes = new ShapeRenderer();
shapes.begin(ShapeRenderer.ShapeType.Filled);
shapes.setColor(Color.RED);
shapes.rect(100, 100, 50, 30);
shapes.circle(400, 300, 25);
shapes.end();

shapes.begin(ShapeRenderer.ShapeType.Line);
shapes.line(0, 0, 800, 600);
shapes.end();

Input Handling

// Polling
if (Gdx.input.isKeyPressed(Input.Keys.LEFT)) {
    player.x -= speed * Gdx.graphics.getDeltaTime();
}
if (Gdx.input.isKeyJustPressed(Input.Keys.SPACE)) {
    player.jump();
}
if (Gdx.input.isTouched()) {
    float touchX = Gdx.input.getX();
    float touchY = Gdx.input.getY();
}

// Event-based input
Gdx.input.setInputProcessor(new InputAdapter() {
    @Override
    public boolean keyDown(int keycode) {
        if (keycode == Input.Keys.ESCAPE) {
            Gdx.app.exit();
            return true;
        }
        return false;
    }

    @Override
    public boolean touchDown(int screenX, int screenY, int pointer, int button) {
        // Convert screen to world coordinates
        Vector3 worldPos = camera.unproject(new Vector3(screenX, screenY, 0));
        handleClick(worldPos.x, worldPos.y);
        return true;
    }
});

// Multiple input processors
InputMultiplexer multiplexer = new InputMultiplexer();
multiplexer.addProcessor(uiStage);
multiplexer.addProcessor(gameInputProcessor);
Gdx.input.setInputProcessor(multiplexer);

Animation

// Sprite sheet animation
Texture sheet = new Texture("walksheet.png");
TextureRegion[][] frames = TextureRegion.split(sheet, 32, 32);
TextureRegion[] walkFrames = frames[0]; // First row

Animation<TextureRegion> walkAnimation = new Animation<>(0.1f, walkFrames);
walkAnimation.setPlayMode(Animation.PlayMode.LOOP);

float stateTime = 0;

// In render loop
stateTime += Gdx.graphics.getDeltaTime();
TextureRegion currentFrame = walkAnimation.getKeyFrame(stateTime, true);
batch.draw(currentFrame, x, y);

Scene2D UI

Stage stage = new Stage(new ScreenViewport());
Gdx.input.setInputProcessor(stage);

Skin skin = new Skin(Gdx.files.internal("uiskin.json"));

Table table = new Table();
table.setFillParent(true);
stage.addActor(table);

Label titleLabel = new Label("My Game", skin, "title");
TextButton playButton = new TextButton("Play", skin);
TextButton quitButton = new TextButton("Quit", skin);

playButton.addListener(new ChangeListener() {
    @Override
    public void changed(ChangeEvent event, Actor actor) {
        game.setScreen(new GameScreen(game));
    }
});

table.add(titleLabel).padBottom(40).row();
table.add(playButton).width(200).height(50).padBottom(10).row();
table.add(quitButton).width(200).height(50);

// In render
stage.act(delta);
stage.draw();

Physics (Box2D)

World world = new World(new Vector2(0, -9.8f), true);

// Create ground
BodyDef groundDef = new BodyDef();
groundDef.position.set(400 / PPM, 0);
Body groundBody = world.createBody(groundDef);
PolygonShape groundShape = new PolygonShape();
groundShape.setAsBox(400 / PPM, 10 / PPM);
groundBody.createFixture(groundShape, 0);
groundShape.dispose();

// Create dynamic body
BodyDef playerDef = new BodyDef();
playerDef.type = BodyDef.BodyType.DynamicBody;
playerDef.position.set(200 / PPM, 300 / PPM);
Body playerBody = world.createBody(playerDef);

CircleShape circle = new CircleShape();
circle.setRadius(16 / PPM);
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = circle;
fixtureDef.density = 1.0f;
fixtureDef.friction = 0.4f;
fixtureDef.restitution = 0.3f;
playerBody.createFixture(fixtureDef);
circle.dispose();

// Step physics in render loop
world.step(1/60f, 6, 2);

Configuration

// Desktop launcher configuration
public class DesktopLauncher {
    public static void main(String[] args) {
        Lwjgl3ApplicationConfiguration config = new Lwjgl3ApplicationConfiguration();
        config.setTitle("My Game");
        config.setWindowedMode(800, 600);
        config.setResizable(true);
        config.setForegroundFPS(60);
        config.setWindowIcon("icon128.png", "icon32.png", "icon16.png");
        new Lwjgl3Application(new MyGame(), config);
    }
}

// Android launcher
public class AndroidLauncher extends AndroidApplication {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
        config.useAccelerometer = false;
        config.useCompass = false;
        initialize(new MyGame(), config);
    }
}

Advanced Usage

// Asset manager for async loading
AssetManager manager = new AssetManager();
manager.load("player.png", Texture.class);
manager.load("music.mp3", Music.class);
manager.load("map.tmx", TiledMap.class);

// In render loop (loading screen)
if (manager.update()) {
    // All assets loaded
    Texture player = manager.get("player.png", Texture.class);
}
float progress = manager.getProgress(); // 0.0 to 1.0

// Tiled map rendering
TiledMap map = manager.get("map.tmx", TiledMap.class);
OrthogonalTiledMapRenderer mapRenderer = new OrthogonalTiledMapRenderer(map);
mapRenderer.setView(camera);
mapRenderer.render();

// Particle effects
ParticleEffect effect = new ParticleEffect();
effect.load(Gdx.files.internal("explosion.p"), Gdx.files.internal(""));
effect.setPosition(x, y);
effect.start();

// In render
effect.update(delta);
batch.begin();
effect.draw(batch);
batch.end();

// Custom shaders
ShaderProgram shader = new ShaderProgram(
    Gdx.files.internal("vertex.glsl"),
    Gdx.files.internal("fragment.glsl")
);
batch.setShader(shader);

Troubleshooting

IssueSolution
”Texture not found”Place assets in assets/ folder; use Gdx.files.internal()
Black screenCheck batch.begin() and batch.end() calls; verify camera setup
Android build failsCheck Android SDK path in local.properties; update Gradle
HTML5 reflection errorsAdd classes to GdxDefinition.gwt.xml for GWT compilation
Memory leak / OutOfMemoryCall .dispose() on all disposable objects
Touch coordinates invertedY-axis is flipped; use camera.unproject() to convert
Texture bleedingAdd padding to texture atlas; use TextureFilter.Nearest for pixel art
Desktop FPS dropsProfile with Gdx.graphics.getFramesPerSecond(); reduce draw calls
Box2D units wrongUse pixels-per-meter (PPM) constant; don’t mix pixel and physics units
Music not loopingSet music.setLooping(true) before calling play()