Category Archives: LibGDX

LibGDX send HTTP request

Check out Lines Galaxy Android game to view the results in action.

Most common ways to communicate between your mobile app to your backend servers are HTTP Requests and Websockets.

In this article I’ll describe how you can create, send and process a HTTP Request to backend servers from your LibGDX application. In this example I will demonstrate how to send a basic POST request.

First step is to prepare the request payload:

Map<String, String> parameters = new HashMap<String, String>();

parameters.put("token", "<TOKEN>");
parameters.put("some_value", 1234);

final Json json = new Json();
json.setTypeName(null);
json.setOutputType(JsonWriter.OutputType.json);
json.setUsePrototypes(false);
String requestJson = json.toJson(parameters);

Second step is to create an instance of the HTTP Agent:

Net.HttpRequest request = new Net.HttpRequest(Net.HttpMethods.POST);
request.setUrl("http://example.com/");
request.setContent(requestJson);

And finally, after we set the desired server url and prepared the payload, we can send the request and attach the callback listeners

Gdx.net.sendHttpRequest(request, new Net.HttpResponseListener() {
    public void handleHttpResponse(Net.HttpResponse httpResponse) {
        HttpStatus status = httpResponse.getStatus();
        if(status.getStatusCode() == 200) {
            String responseJson = httpResponse.getResultAsString();
        } else {
            // error :(
        }
    }
    public void failed(Throwable t) {
        String error = t.getMessage();
    }
    public void cancelled() {
        // request aborded
    }
});

And that’s it. ou can just copy the above code and send LibGDX HTTP Request. You can dig further by reading the official docs: HttpResponseListener, HttpRequest.

Check out Lines Galaxy Android game to view the results in action.

How to create custom Dialog in LibGDX

This article describes how to programatically create a custom dialog using LibGDX framework.

Check out Lines Galaxy Android game to view the results in action.

LibGDX tutorials describe how to achieve this using graphic resources packed in a sprite together with a skin.

The test resources can be found here but for this specific task you’ll only need the following ones:

  1. Atlas
  2. Atlas Image
  3. Skin JSON
  4. Font Image
  5. Font File

You would just load the skin with all its assets (9patches, fonts, atlas with sprite) and pass it to the Dialog constructor:

    Skin skin = new Skin(Gdx.files.internal("uiskin.json"));
    // fire up the dialog and voila :)
    Dialog d = new Dialog("Title", skin);

This will work for most scenarios.

However, I wanted to programatically be able to change the dialog properties and style.

Notice: this tutorial only covers a dialog that uses the following elements: title, description, spacing, buttons, background and stage background; for all other items (checkbox, scrollbar, select) you’re better off using images for each component.

The Prerequisites

Following code sequence contains the mandatory styles for the Skin object much needed in the Dialog.

    // This is the Skin that we'll use to design our dialog
    Skin skin = new Skin();

    // We have two backgrounds to handle and two possible approaches depending on the design you need
    // Using a 9 patch (it can contain the header of the dialog)
    TextureRegion texture_region = App.res_atlas.findRegion("9patch_bg");
    Sprite sprite = new Sprite(texture_region);
    NinePatch np = new NinePatch(sprite, 15, 15, 15, 15);
    NinePatchDrawable npd = new NinePatchDrawable(np);

    // Using a Pixmap
    Pixmap dialog_sbg = new Pixmap(App.screen_width, App.screen_height, Pixmap.Format.RGB888);
    dialog_sbg.setColor(new Color(Color.BLACK.r, Color.BLACK.g, Color.BLACK.b, 1f));
    dialog_sbg.fill();

    // The only mandatory resource required for a Dialog is the WindowStyle
    Window.WindowStyle ws = new Window.WindowStyle();

    // We're using the 9patch drawable as the dialog element background
    ws.background = npd;
    // For the whole screen dialog background we're using the pixmap
    ws.stageBackground = new Image(new Texture(dialog_sbg)).getDrawable();
    ws.titleFont = App.manager.get("droidsansmono-regular-11.ttf", BitmapFont.class);
    ws.titleFontColor = Color.RED;

    // This WindowStyle needs to be set as the default style in the skin
    skin.add("default", ws);

    // We can now init the Dialog
    final CustomDialog cd = new CustomDialog("", skin);

We now have the Skin ready with a black fullscreen background and a grey window.

The CustomDialog Class

I’ve wrapped the Dialog in a CustomDialog class. This allows me to set the dialog properties once and then reuse the same dialog without a new setup.

    public class DialogAlert extends Dialog {

        private float dialog_width = (float)(260*App.density);
        private float dialog_height = (float)(180*App.density);
        private float dialog_padding = (float)(20*App.density);
        private float button_height = (float)(40*App.density);
        private float button_width = (float)(200*App.density);
        private float button_pad_h = (float)(15*App.density);

        public DialogAlert(String title, Skin skin) {
            super(title, skin);
            setup();
        }

        // Set certain sizes and options
        private void setup() {

            padLeft(dialog_padding);
            padRight(dialog_padding);
            padBottom(dialog_padding);
            getButtonTable().defaults().height(button_height);
            getContentTable().defaults().width(dialog_width);

            setModal(true);
            setMovable(false);
            setResizable(false);

        }

        // Set the properties of the description Label
        @Override
        public DialogAlert text(String text) {

            Label label = new Label(text, new Label.LabelStyle(App.manager.get("font-11.ttf", BitmapFont.class), Color.WHITE));
            label.setAlignment(Align.center);
            label.setWrap(true);
            label.setWidth(dialog_width-dialog_padding*2);

            text(label);

            return this;

        }

        // The "YES"
        // In my case I wanted it to be slightly more pronounced so I used a basic 9patch
        public DialogAlert buttonYay(String buttonText, InputListener listener) {

            TextButton.TextButtonStyle textButtonStyle = new TextButton.TextButtonStyle();
            TextureRegion regionOn = App.graphics_atlas.findRegion("button", 1);
            Sprite s = new Sprite(regionOn);
            NinePatch onNinePatch = new NinePatch(s, 14, 14, 14, 14);
            NinePatchDrawable ninePatchDrawable = new NinePatchDrawable(onNinePatch);

            textButtonStyle.up = ninePatchDrawable;
            textButtonStyle.down = ninePatchDrawable;
            textButtonStyle.checked = ninePatchDrawable;
            textButtonStyle.over = ninePatchDrawable;
            textButtonStyle.disabled = ninePatchDrawable;
            textButtonStyle.font = App.manager.get("font-15.ttf", BitmapFont.class);
            textButtonStyle.fontColor = Color.WHITE;

            TextButton button = new TextButton(buttonText, textButtonStyle);
            button.setSize(button_width, (float)(44*App.density));
            button.addListener(listener);
            button.padLeft(button_pad_h);
            button.padRight(button_pad_h);
            button(button);

            return this;

        }

        // The "NO" button has a different design compared to the "YES" button
        // In this example it's a transparent background with a white text
        public DialogAlert buttonNay(String buttonText, InputListener listener) {

            TextButton.TextButtonStyle textButtonStyle = new TextButton.TextButtonStyle();
            textButtonStyle.font = App.manager.get("font-15.ttf", BitmapFont.class);
            textButtonStyle.fontColor = Color.WHITE;

            TextButton button = new TextButton(buttonText, textButtonStyle);
            button.setSize(button_width, (float)(44*App.density));
            button.addListener(listener);
            button.padLeft(button_pad_h);
            button.padRight(button_pad_h);
            button(button);

            return this;

        }

        @Override
        public float getPrefWidth() {
            return dialog_width;
        }

        @Override
        public float getPrefHeight() {
            return dialog_height;
        }

    }

The sizing might need to be updated to fit your needs.
After you done all this you can open the modal and pass the options like shown bellow:

    final CustomDialog cd = new CustomDialog("", skin);
    da.text("Congratulations!\nYou just created a custom dialog!")
        .buttonYay("YES I DID", new InputListener() {
            public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
                // blow up the universe or just draw the pixels
                return true;
            }
        })
        .buttonNay("NOOO", new InputListener() {
            public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
                // maybe some actions here?
                da.hide();
                return true;
            }
        })
        .show(stage); // you'll need a Stage instance :D

The Result Dialog

custom dialog libgdx android

Leave a comment if you’ve got to a better solution for programmatic designing of Libgdx Dialog.

Maybe you’re also interested in LibGDX Buttons using 9patch tutorial or check out Lines Galaxy Android game to view the results in action.

Build Version increment with Gradle build script

Check out Lines Galaxy Android game to view the results in action.

Make your Gradle build script handle the apk version for you!

Your second Google Play Console release will most certainly end at the APK upload. This would probably be caused by the fact that the APK build version was not incremented.

Yes, this was also my case. I was like whaaat? what version? ooh nooo…

Have no worries. I searched for a way which would handle the build version number automatically. I also wanted to allow the developer to manage certain properties of the version. The solution which I came to works pretty nice for my needs and probably yours if you’re reading this.

The build scripts are also handling two types of releases: beta (debug) and production.

Each version has its own API keys, features enabled/disabled, application ids, icons and names. This is what I needed but after a certain point having custom properties for each release type will be a piece of cake.

Customizing the Gradle script to handle build version

First of all you’ll need a way to store the current version. This file should be included in the versioning system. Let’s call it build.properties. Place the file in your android folder and add these contents:

VERSION_NUMBER=1
VERSION_BUILD=0
VERSION_PATCH=0

Obviously the version_number should start with 1. This value and version_patch will be automatically incremented each time you’ll do an assembleRelease.

When you upload an APK each version should be higher than the previous uploaded one.

Version_build will be incremented which each build and is mainly for debug.

Next thing we need to handle is the gradle script. The followind script is added in android task.

android {
    ...

    // read the current state of the build version properties
    def buildPropertiesFile = file('build.properties')
    def value = 0

    // the major and minor properties need to be manually incremented by the dev
    // the resulting version could be used for identifying the apk on Google Play Console
    def versionMajor = 1
    def versionMinor = 0

    if(!buildPropertiesFile.canRead()) {
        throw new GradleException("Could not read build.properties")
    }

    // load the properties from the file
    def Properties buildProperties = new Properties()
    buildProperties.load(new FileInputStream(buildPropertiesFile ))

    // we only want to increment the number and patch for release builds
    // you'll need to check the exact name of the build task - it might be assembleRelease (without android:)
    def runTasks = gradle.startParameter.getTaskNames()
    if('android:assembleRelease' in runTasks || 'android:assembleProductionRelease' in runTasks) {
        value = 1;
    }

    def versionNumber = buildProperties['VERSION_NUMBER'].toInteger() + value
    def versionPatch = buildProperties['VERSION_PATCH'].toInteger() + value
    def versionBuild = buildProperties['VERSION_BUILD'].toInteger() + 1
    
    buildProperties['VERSION_NUMBER'] = versionNumber.toString()
    buildProperties['VERSION_PATCH'] = versionPatch.toString()
    buildProperties['VERSION_BUILD'] = versionBuild.toString()

    // save the build state
    versionProps.store(buildPropertiesFile.newWriter(), null)

    defaultConfig {
        applicationId "com.example.name"
        minSdkVersion 15
        targetSdkVersion 25
        versionCode versionNumber
        versionName "${versionMajor}.${versionMinor}.${versionPatch}.${versionBuild}"
    }
    productFlavors {
        beta {
            applicationIdSuffix ".beta"
            versionNameSuffix "-SNAPSHOT" + getDate()
        }
        production {
        }
    }
    buildTypes {
        release {
            minifyEnabled true
            proguardFile 'proguard-project.txt'
            applicationVariants.all { variant ->
                variant.outputs.each { output ->
                    def SEP = "_"
                    def flavor = variant.productFlavors[0].name
                    def buildType = variant.variantData.variantConfiguration.buildType.name
                    def version = variant.versionName
                    def date = new Date();
                    def formattedDate = date.format('ddMMyy_HHmm')

                    def apkName= applicationId+SEP+flavor+SEP+buildType+SEP+version+SEP+formattedDate+".apk"

                    output.outputFile = new File(output.outputFile.parent, apkName)
                }
            }
        }
    }
    ...
}

That’s it! Your apk build version will now be handled automatically so you can focus on what’s important.

My other Android posts could be of interest to you! Check them out or check out Lines Galaxy Android game to view the results in action.

How to integrate Rewarded Video Ad in LibGDX

Check out Lines Galaxy Android game to view the results in action.

What is Rewarded Video Ad?

Rewarding users with different in-app coins or features can be done using Rewarded Video Ad.

This might be an advertising solution that could be accepted by users whilst supporting the development of a free mobile application.

Most games tend to place the user in a situation where he is stuck or he needs some coins in order to unlock a certain feature.

The user is then given the possibility to tap a button or an element which will open a full screen video.

At the end of this video called Rewarded Video Ad the player will receive his prize.

Let’s get started with Rewarded Video Ad!

Integrating Rewarded Video Ads in LibGDX is quite easy.

You’ll need to import a few packages (AndroidLauncher.java):

import com.google.android.gms.ads.MobileAds;
import com.google.android.gms.ads.reward.RewardItem;
import com.google.android.gms.ads.reward.RewardedVideoAd;
import com.google.android.gms.ads.reward.RewardedVideoAdListener;

public class AndroidLauncher extends AndroidApplication implements GoogleServices, RewardedVideoAdListener {
    private RewardedVideoAd adRewardedVideoView;
    private static final String REWARDED_VIDEO_AD_UNIT_ID = "ca-app-pub-3940256099942544/5224354917";
    private VideoEventListener vel;
}

Our Android Launcher has one member which will store the RewardedVideoAd object.

Initialing the Rewarded Video Ad requires an ad unit. The one in this example contains a test value provided by AdMob.

While developing the application this is the unit id that you should use.

As soon as you’re ready to deploy into production you can switch to your real unit id obtained from AdMob website.

The vel member will be used for sharing Rewarded Video Ads events in other classes.

Next thing we need is to initiate the Rewarded Video Ad, to set the event listener and to start loading the first video so it will be ready when we need it (AndroidLauncher.java):

public void loadRewardedVideoAd() {
    adRewardedVideoView.loadAd(REWARDED_VIDEO_AD_UNIT_ID, new AdRequest.Builder().build());
}

public void setupRewarded() {
    adRewardedVideoView = MobileAds.getRewardedVideoAdInstance(this);
    adRewardedVideoView.setRewardedVideoAdListener(this);
    loadRewardedVideoAd();
}

Above code does not need any extra explications. Method names have been carefully chosen so they’re quite self explanatory.
While using Rewarded Video Ads we’ll need a way to know if the video is loaded and if it’s not loaded we need to load it.
In our Android Launcher class we’ll add a new private boolean is_video_ad_loaded (AndroidLauncher.java).

public boolean hasVideoLoaded(){
    if(is_video_ad_loaded) {
        return true;
    }
    runOnUiThread(new Runnable() {
        public void run() {
            if (!adRewardedVideoView.isLoaded()) {
                loadRewardedVideoAd();
            }
        }
    });
    return false;
}

Following method will show the add if it’s loaded or load an new ad (AndroidLauncher.java).

public void showRewardedVideoAd(){
    runOnUiThread(new Runnable() {
        public void run() {
            if (adRewardedVideoView.isLoaded()) {
                adRewardedVideoView.show();
            } else {
                loadRewardedVideoAd();
            }
        }
    });
}

The Android Launcher is the class that initiates your application and you should only have the code for this purpose here.

You’ll want to interact with the Rewarded Video Ad instance and one way of doing this is to implement some interfaces.

In my code there’s GoogleServices interface which looks like this (GoogleServices.java):

public interface GoogleServices {
    public boolean hasVideoLoaded();
    public void loadRewardedVideoAd();
    public void showRewardedVideoAd();
    public void setVideoEventListener(VideoEventListener listener);
}

Again not many details are required here. The VideoEventListener is another interface which only handles the Rewarded Video Ad events (VideoEventListener.java):

public interface VideoEventListener {
    void onRewardedEvent(String type, int amount);
    void onRewardedVideoAdLoadedEvent();
    void onRewardedVideoAdClosedEvent();
}

I only needed handlers for these events in my other classes but you can customize it for your needs.

We’ll need some handlers for the above events: (Android Launcher.java):

@Override
public void onRewarded(RewardItem reward) {
    if(vel != null) {
        // The type and the amount can be set in your AdMob console
        vel.onRewardedEvent(reward.getType(), reward.getAmount());
    }
}

// Each time the video ends we need to load a new one
@Override
public void onRewardedVideoAdClosed() {
    is_video_ad_loaded = false;
    loadRewardedVideoAd();
    if(vel != null) {
        vel.onRewardedVideoAdClosedEvent();
    }
}

@Override
public void onRewardedVideoAdLoaded() {
    if(vel != null) {
        vel.onRewardedVideoAdLoadedEvent();
    }
    is_video_ad_loaded = true;
}

Once this is added you can now attach the video event listener (AndroidLauncher.java):

public void setVideoEventListener (VideoEventListener listener) {
    this.vel = listener;
}

This is all the needed setup.
Last thing we need to do is initiate the Rewarded Video Ad in our onCreate method (AndroidLauncher.java):

@Override
protected void onCreate (Bundle savedInstanceState) {
    ...
    View gameView = initializeForView(new App(this), config);
    setupRewarded();
    ...
}

That’s all! The integration is now finished!

You can now use the Rewarded Video Ad in your applications classes (App.java):

public class App extends Game implements VideoEventListener {

    public GoogleServices googleServices;

    public App(GoogleServices googleServices) {

        this.googleServices = googleServices;
        this.googleServices.setVideoEventListener(this);

        // this probably should not be here but it's how you show the video
        if(this.googleServices.hasVideoLoaded()) {
            this.googleServices.showRewardedVideoAd();
        }

   }

    @Override
    public void onRewardedEvent(String type, int amount) {
        // player has just finished the video and was rewarded
    }

    @Override
    public void onRewardedVideoAdLoadedEvent() {
        // video is ready and can be presented to the player
    }

    @Override
    public void onRewardedVideoAdClosedEvent() {
        // player has closed the video so no reward for him
    }

}

Checkout my other LibGDX posts or Lines Galaxy Android game to view the results in action.

2d animations using sprites in LibGDX

Check out Lines Galaxy Android game to view the results in action.

2d animations of entities in LibGDX can be done in multiple ways.

One option would be to draw each pixel – not that easy but the result would be great. Second option is using textures – similar to sprite sheets but for other purposes.

The last option that I know of and that is described here is using a set of images packed together in a larger image named sprite.

2d animations can be created quite fast using these sprites.  The sprite does not need to have a text file describing the contents of it – sizes, positions, etc. All you need to know is how many rows and columns your animation has.

The bellow code sequence creates a continuous animation using a 5×1 frames sprite.

Here’s how you can create LibGDX 2d animations using sprites:

// you'll manage the imports
public class MyAnimationClass {

    public static Texture bounce_sprite;
    private static final int COLS = 5;
    private static final int ROWS = 1;

    static Animation bounce_animation;
    static TextureRegion[] bounce_frames;
    static TextureRegion current_frame;
    static float state_time;

    @Override
    public void create () {

        bounce_sprite = new Texture(Gdx.files.internal("bounce_sprite.png"));
       TextureRegion[][] tmp = TextureRegion.split(bounce_sprite, bounce_sprite.getWidth()/COLS, bounce_sprite.getHeight()/ROWS);
        bounce_frames = new TextureRegion[COLS * ROWS];
        int index = 0;
        for(int y=0; y<ROWS; ++y) {
            for(int x=0; x<COLS; ++x) {
                bounce_frames[index++] = tmp[y][x];
            }
        }
        bounce_animation = new Animation(0.1f, bounce_frames);
        state_time = 0f;

    }

    @Override public void render () {

        Gdx.gl.glClearColor(1,1,1,1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        batch.begin();

        state_time += delta;
        current_frame = bounce_animation.getKeyFrame(state_time, true);
        batch.draw(current_frame,
                   x,
                   y,
                   width,
                   height,
                   origin_x,
                   origin_y,
                   scale_x,
                   scale_y,
                   rotation);

        batch.end();

    }
}

That’s all for the basic 2d sprite animation using LibGDX.

In case you want to run the animation only once when some event triggers you could keep the state of the animation in a boolean variable:

// you'll manage the imports
public class MyAnimationClass {

    public static Texture bounce_sprite;
    private static final int COLS = 5;
    private static final int ROWS = 1;

    static Animation bounce_animation;
    static TextureRegion[] bounce_frames;
    static TextureRegion current_frame;
    static float state_time;

    boolean bounce_animation_running;

    @Override
    public void create () {

        bounce_sprite = new Texture(Gdx.files.internal("bounce_sprite.png"));
       TextureRegion[][] tmp = TextureRegion.split(bounce_sprite, bounce_sprite.getWidth()/COLS, bounce_sprite.getHeight()/ROWS);
        bounce_frames = new TextureRegion[COLS * ROWS];
        int index = 0;
        for(int y=0; y<ROWS; y++) {
            for(int x=0; x<COLS; x++) {
                bounce_frames[index++] = tmp[y][x];
            }
        }
        bounce_animation = new Animation(0.1f, bounce_frames);
        state_time = 0f;

        // set this variable true when you want the animation to run once
        bounce_animation_running = true;

    }

    @Override public void render (float delta) {

        Gdx.gl.glClearColor(1,1,1,1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        batch.begin();

        if(bounce_animation_running) {
            state_time += delta;
            current_frame = bounce_animation.getKeyFrame(state_time, true);
            batch.draw(current_frame,
                       x,
                       y,
                       width,
                       height,
                       origin_x,
                       origin_y,
                       scale_x,
                       scale_y,
                       rotation);
            if(bounce_animation.isAnimationFinished(state_time)) {
                state_time = delta;
                bounce_animation_running = false;
            }
        }

        batch.end();

    }
}

Obviously a more detailed example can be found on the Github LibGDX page, but if you want to skip dirrectly to the code, this should help you get started.

Here’s the sprite used in this demo:

2d animations bounce sprite

Check out Lines Galaxy Android game to view the results in action.

How to create LibGDX Buttons from nine patch

Check out Lines Galaxy Android game to view the results in action.

One of the most promising frameworks for creating 2D graphics in Android (and Web, iOS, Windows) is LibGDX.

Drawing complex buttons in 2D graphics is not exactly easy. One option would be to convert your button design into nine patch images and use them in your Android apps.

The bellow class is missing some crucial methods. Bare in mind that only the code required for drawing the buttons in LibGDX is posted here. Copy-pasting the whole class might not work.

Here’s how you can create LibGDX Buttons which use nine patch image packs (the bellow code creates a single button):

// you'll manage the imports
public class MyClass extends ApplicationAdapter {

    private TextureAtlas buttonAtlas;
    private NinePatch buttonNinePatch;
    private TextButton textButton;
    private SpriteBatch batch;

    @Override
    public void create () {

        batch = new SpriteBatch();

        buttonAtlas = new TextureAtlas("buttons.pack");
        buttonNinePatch= buttonAtlas.createPatch("button1");
        NinePatchDrawable ninePatchDrawable = new NinePatchDrawable(buttonNinePatch);
        TextButtonStyle textButtonStyle = new TextButtonStyle();

        // you might want to use different nine patch for each button state
        textButtonStyle.up = ninePatchDrawable;
        textButtonStyle.down = ninePatchDrawable;
        textButtonStyle.checked = ninePatchDrawable;
        textButtonStyle.over = ninePatchDrawable;

        textButtonStyle.font = new BitmapFont();

        // LibGDX Buttons
        textButton = new TextButton("My Button", textButtonStyle);
        textButton.setPosition(0, 0);
        textButton.setSize(200, 200);

    }

    @Override
    public void render () {

        Gdx.gl.glClearColor(1,1,1,1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        batch.begin();
        textButton.draw(batch, 1f);
        batch.end();

    }

}

That’s all.
Now (as President Francis says in House of Cards) “no one said” 2D graphics in Android “will be easy”.

After you’ll run the above code you’ll see that there’s a problem. The font is not exactly as you’d expected. Well you could scale it but it won’t output the expected result and it will actually be pixelated. This is where FreeTypeFontGenerator jumps in.

The next post will cover how to use them in your Android LibGDX app.

Check this post in case you’re not familiar to how buttons.pack works and where it comes from.

Check out Lines Galaxy Android game to view the results in action.

How to generate LibGDX nine patch packs

The first time you’ll try to create valid LibGDX nine patch packs for your Android app you might run into multiple problems.

I’ve created this article so that others can skip all the docs and searches and get right to the magic.

Nine Patch is an image that contains additional information compared to a normal image which is used to determine which areas of it should be scaled when the image is used in a size which is larger than the original one.

Here’s an example of a nine patch image “button1.9.png” (notice the .9. naming convention):

LibGDX nine patch

This article does not explain how to generate these images but how to create the packs which can be used in your Android app. After your designer provides you with similar nine patch images to the one above, or if you manage to create ones, you’ll need to download LibGDX Texture Packer GUI. The latest version should do just fine.

In order to run it you’ll need to have Java installed. Place all your nine patch images inside a folder then specify this folder as the input directory in Texture Packer GUI. Give the pack whatever name you desire (mine is named buttons.pack) then hit the Pack’em all after you select your output directory.

You should now have a sprite named buttons.png which contains all your nine patch images and a file which contains the pack configuration and which is similar to the one bellow:

buttons.png
format: RGBA8888
filter: Nearest,Nearest
repeat: none
button1
  rotate: false
  xy: 0, 198
  size: 198, 198
  split: 38, 38, 15, 13
  orig: 0, 0
  offset: 0, 0
  index: 80

That’s all.

Now that you have the packs in your virtual hands go ahead to the next article and use them.

The next post will cover how to create buttons in LibGDX using the generated packs.