Run this every time you change your art. Put it in a Gradle task so you never forget. Step 4: Loading the Atlas in LibGDX Once packed, you get two files: ui-atlas.atlas and ui-atlas.png . Copy these to your Android/assets folder.
public class AtlasPacker public static void main(String[] args) // Settings TexturePacker.Settings settings = new TexturePacker.Settings(); settings.maxWidth = 2048; settings.maxHeight = 2048; settings.pot = true; // Power of two (required for legacy devices) settings.filterMin = TextureFilter.Nearest; settings.filterMag = TextureFilter.Nearest; // Input: raw images, Output: folder for assets TexturePacker.process(settings, "../raw-assets/ui", "../android/assets/ui", "ui-atlas"); System.out.println("Packing complete!"); texturepacker libgdx
// Before Texture playerTex = new Texture("player.png"); // After (no logic change needed in your entity class) TextureRegion playerTex = gameAtlas.findRegion("player"); 1. 9-Patch (Scalable UI) Name your raw files with .9 (e.g., panel.9.png ). In TexturePacker GUI, enable StripWhitespace and Ignore blanks . LibGDX will automatically load them as NinePatch objects. 2. Pixel Perfect (Retro Games) If you make pixel art, turn off filtering (set to Nearest ) and turn on edgePadding = false to prevent bleeding between sprites. 3. Debug Visualization LibGDX has a built-in debugger for atlases. Render this to see if your packing is efficient (red = empty space): Run this every time you change your art
// Instead of loading 100 textures... TextureAtlas gameAtlas = new TextureAtlas(Gdx.files.internal("ui/ui-atlas.atlas")); // Grab a single region TextureRegion buttonRegion = gameAtlas.findRegion("green_button_01"); Copy these to your Android/assets folder
SpriteBatch batch = new SpriteBatch(); TexturePacker.renderDebugImage(gameAtlas, batch, 0, 0); | Problem | Solution | | :--- | :--- | | White lines around sprites | Enable edgePadding and duplicatePadding in settings. | | "Texture too large" error | Lower maxWidth to 1024 or 512. (Or check GPU limits). | | Animation frames out of order | Name files run_01.png , run_02.png . The packer sorts alphanumerically. | | AssetManager reload crash | Don't create a new TextureAtlas for every screen. Dispose the old one first. | Final Verdict: Don't Ship Without It I’ve seen prototype LibGDX games run at 25 FPS. After packing the UI and sprites into 2 atlases, they jumped to 60 FPS instantly.
// Or create an AtlasSprite for advanced animation AtlasSprite cursorSprite = new AtlasSprite(gameAtlas.findRegion("cursor")); Here’s where the magic happens. You don't need to change your code logic.
Run this every time you change your art. Put it in a Gradle task so you never forget. Step 4: Loading the Atlas in LibGDX Once packed, you get two files: ui-atlas.atlas and ui-atlas.png . Copy these to your Android/assets folder.
public class AtlasPacker public static void main(String[] args) // Settings TexturePacker.Settings settings = new TexturePacker.Settings(); settings.maxWidth = 2048; settings.maxHeight = 2048; settings.pot = true; // Power of two (required for legacy devices) settings.filterMin = TextureFilter.Nearest; settings.filterMag = TextureFilter.Nearest; // Input: raw images, Output: folder for assets TexturePacker.process(settings, "../raw-assets/ui", "../android/assets/ui", "ui-atlas"); System.out.println("Packing complete!");
// Before Texture playerTex = new Texture("player.png"); // After (no logic change needed in your entity class) TextureRegion playerTex = gameAtlas.findRegion("player"); 1. 9-Patch (Scalable UI) Name your raw files with .9 (e.g., panel.9.png ). In TexturePacker GUI, enable StripWhitespace and Ignore blanks . LibGDX will automatically load them as NinePatch objects. 2. Pixel Perfect (Retro Games) If you make pixel art, turn off filtering (set to Nearest ) and turn on edgePadding = false to prevent bleeding between sprites. 3. Debug Visualization LibGDX has a built-in debugger for atlases. Render this to see if your packing is efficient (red = empty space):
// Instead of loading 100 textures... TextureAtlas gameAtlas = new TextureAtlas(Gdx.files.internal("ui/ui-atlas.atlas")); // Grab a single region TextureRegion buttonRegion = gameAtlas.findRegion("green_button_01");
SpriteBatch batch = new SpriteBatch(); TexturePacker.renderDebugImage(gameAtlas, batch, 0, 0); | Problem | Solution | | :--- | :--- | | White lines around sprites | Enable edgePadding and duplicatePadding in settings. | | "Texture too large" error | Lower maxWidth to 1024 or 512. (Or check GPU limits). | | Animation frames out of order | Name files run_01.png , run_02.png . The packer sorts alphanumerically. | | AssetManager reload crash | Don't create a new TextureAtlas for every screen. Dispose the old one first. | Final Verdict: Don't Ship Without It I’ve seen prototype LibGDX games run at 25 FPS. After packing the UI and sprites into 2 atlases, they jumped to 60 FPS instantly.
// Or create an AtlasSprite for advanced animation AtlasSprite cursorSprite = new AtlasSprite(gameAtlas.findRegion("cursor")); Here’s where the magic happens. You don't need to change your code logic.