Tag 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.