Tuesday, May 22, 2018

Creating Sprites with libGDX texturepacker

One of the differences between using libGDX and and not using a game engine is that libGDX uses sprite sheets. This is good, because in OpenGL, binding textures is fairly resource expensive and it is better to bind one large resource once than many small resources.

There are plenty of tutorials online about creating sprites, and I am certainly not much of an artist, so I will leave that to others to explain. But, I will say this, if you are like me and end up with a GIF file or have each of your individual sprites saved as layers in a single image there is a trick to getting them out without saving individually.

To separate layers of an image file into separate images the easy way, save the image file as an OpenRaster file (.ora extension). GIMP can do this for free, and likely most other image editing software can as well. After saving, open the .ora file using compression software (7zip or WinRAR), open the 'data' folder, and you will see each individual layer saved as a separate .png file. Easy.

Otherwise, it is important that each of your animation frames is in numerical (or alphabetical) order so that the sprite sheet will be created in the proper order. In my case, I number each frame like 001.png, 002.png, 003.png and so on.

For this tutorial, I made a simple 12 frame animation of a dot running (the app I am making is called Dot's Dots*, right?). You can see it in GIF form below, but I won't provide the images or the sprite sheet for you, because I think it is important that you try this for yourself. And honestly, you don't even need to make it 12 frames, you could have a 3-4 frame animation of a stick man walking and it will be fine.



Now, hopefully you created a simple animation of a few frames. In order to create your sprite sheet the first thing you should do is download the texture packer JAR file. Save it somewhere convenient, and use the following command at the command line to create the sprite sheet:

// OS X / Linux java -cp runnable-texturepacker.jar com.badlogic.gdx.tools.texturepacker.TexturePacker [inputDir] [outputDir] [packFileName]

// WINDOWS java -cp runnable-texturepacker.jar com.badlogic.gdx.tools.texturepacker.TexturePacker [inputDir] [outputDir] [packFileName]

[inputDir] is where you saved your individual image files, [outputDir] is where you would like the sprite sheet to be saved and [packFileName] is going to be the name of the output file.

In my case, I want to take my image files and save the sprite sheet directly into my apps assets folder. Because I am using Linux, I would type this:

java -cp runnable-texturepacker.jar com.badlogic.gdx.tools.texturepacker.TexturePacker 'Images/Sprites/DotsDots' '/home/netbook/AndroidStudioProjects/dotsdots/android/assets' dotsprite

After the texture packer runs, you will find two types of file in the output directory. There will be the .png files, which will be the actual sprite sheets, and there will be the .atlas file. The .atlas file is a text file that tells libGDX the location of each individual image on the sprite sheet.

If you want to just make a simple sprite sheet, feel free to stop reading here. I will discuss slightly little more technical stuff below, but it likely won't affect sprite or animation performance.

Note that the texturepacker defaults to sprite sheets that are 1024px x 1024px. In 2018 that seems fairly paltry, and if you want to change the sheet size, or any other options, you just need to include a file called 'pack.json' in the same directory as your individual image files. The pack.json file can have the following options:

{

pot: true,
paddingX: 2,
paddingY: 2,
bleed: true,
bleedIterations: 2,
edgePadding: true,
duplicatePadding: false,
rotation: false,
minWidth: 16,
minHeight: 16,
maxWidth: 1024,
maxHeight: 1024,
square: false,
stripWhitespaceX: false,
stripWhitespaceY: false,
alphaThreshold: 0,
filterMin: Nearest,
filterMag: Nearest,
wrapX: ClampToEdge,
wrapY: ClampToEdge,
format: RGBA8888,
alias: true,
outputFormat: png,
jpegQuality: 0.9,
ignoreBlankImages: true,
fast: false,
debug: false,
combineSubdirectories: false,
flattenPaths: false,
premultiplyAlpha: false,
useIndexes: true,
limitMemory: true,
grid: false,
 scale: [ 1 ],
scaleSuffix: [ "" ],
scaleResampling: [ bicubic ]

}

You only need to include the options you want to change, any unlisted options will just return to the default settings. As for the sprite sheet size, I believe that on most modern devices that sheets of 4096px x 4096px will work fine. However, old devices, particularly those using old versions of OpenGL, will not work. I thought about this personally, and decided that it was more important for me to maintain backwards compatibility than it is to minimize texture binding resource use, so I decided to stay with the default. Of course that decision is up to each developer, so you can decide on your own.

Next, if your images don't fit all onto one sprite sheet, it might be a good idea to separate them into subdirectories in your input directory. By doing this, you can ensure that the texturepacker saves related files on the same sprite sheets. Because the libGDX texturepacker tries to create the most efficient packing result, related sprites could be spread across several sprite sheets, which would be very inefficient.

Finally, if you want to run the texturepacker as part of your app, it can be done. We won't cover it here, because it seems to be of limited value to hobbyist developers that are likely working alone, but the libGDX wiki discusses it in detail.

*I have no idea what Dot's Dots is going to turn out to be, I am creating it on the fly as part of this tutorial. Shhhh!

Monday, May 14, 2018

Compiling Your libGDX Project

So now that you have imported a libGDX project into Android Studio, you will probably notice that it doesn't look like a normal Android Studio project, and also that it won't compile right away.

This tutorial will explain the changes needed to be made so that you can compile your libGDX project for Android, desktop and HTML.

Android:

So if you tried to compile your new project you probably got a Gradle error that looks something like this:


What happens here is that currently (as of early 2018) projects imported from libGDX use a Gradle version of something like 2.14.1 and libGDX needs a Gradle version of 3.5 or above. Conversely, you will also get an error if you are using any Gradle version above 4.0, which would be the default of Android Studio. In either case, we want to change the Gradle version. To do this, we open the 'gradle-wrapper.properties' file under the 'Gradle Scripts' heading in the Project window.

We want to change the distributionURL line to:
distributionUrl=https\://services.gradle.org/distributions/gradle-3.5-all.zip
If you followed my previous tutorial in setting up the libGDX project in Android Studio, this should be all you need to do in order to make the APK able to be compiled.

If you are still having trouble, here are some other problems I have faced.

Error:(2, 0) Plugin with id 'jetty' not found

This error is caused when you are using a Gradle version above 4.0. Follow the steps above to change the Gradle version to 3.5, but additionally follow these steps:

1. Open the project level 'build.gradle' file (again under the 'Gradle Scripts' heading in the Project window)
2. Change the 'classpath' version:
classpath 'com.android.tools.build:gradle:2.3.3'
3. In the same file, under 'repositories' remove:
google()
NOTE: There are two places to do #3, under 'buildscript' and under 'allprojects'

Error: Plugin with id 'gwt' not found

If you run into this error, there is a simple solution. Just go into the project level 'build.gradle' file (again under the 'Gradle Scripts' heading in the Project window) and add the following line under the 'dependencies' inside the 'buildscript' tag:
classpath 'de.richsource.gradle.plugins:gwt-gradle-plugin:0.6'

Desktop: 

The easiest way to compile to desktop is to create a runnable JAR file. To do this, open the Gradle window by clicking the vertical 'Gradle' button on the right side. In that menu, expand ':desktop', then expand 'other', and finally click on 'dist'.

Once it is finished compiling, you can find the JAR file in this directory:
[APPLICATION PATH]/desktop/build/libs

If you end up having an error, read below.

Running the desktop app from Android Studio

This is easy, once you know what to do. Go into the Project Window and expand the 'Desktop' folder. Several folders will open and at the end there will be a java file 'DesktopLauncher'. Right click that and select 'Run DesktopLauncher.main()'. Unfortunately, this will cause an error. It will say something like Exception in thread "LWJGL Application" com.badlogic.gdx.utils.GdxRuntimeException: Couldn't load file: badlogic.jpg. If this is the case, the answer is simple.

Go into the run menu at the top of the Android Studio window and click on 'Edit Configurations...' This will open the Run/Debug Configurations Menu. Click on 'DesktopLauncher' from the dropdown menu on the left. Now, on the right side you can see an item called 'Working directory:'. To fix this error just append 'android/assets' to the directory listed. It should look like:
[APPLICATION PATH]/android/assets

This should allow it to run, but if you have another error see below.

"Exception in thread 'main' java.lang.NoClassDefFoundError: com/badlogic/gdx/ApplicationListener"

To solve this problem, we need to run the app as a JAR application. To do this, go into the run menu at the top of the Android Studio window and click on 'Edit Configurations...' This will open the Run/Debug Configurations Menu. In this menu, first click the green plus sign in the top left. Select 'JAR Application' from the drop down menu. You will see something like this:
You need to enter the 'Path to JAR:' which will be:
[APPLICATION PATH]/desktop/build/libs/desktop-1.0.jar
Next, in the 'Before Launch' section at the bottom, hit the green plus and add 'Run Gradle Task'. The 'Gradle Project' should be found at:
[APPLICATION PATH]/desktop/build.gradle
Finally, in the 'Tasks' box, type:
desktop:dist

And that's it. You should be able to run your app on the desktop as a JAR application by clicking the 'Select Run/Debug Configuration' button in the menu and selecting 'JAR Application'. Then just click the green run arrow to the right and wait for it to compile.

HTML:

Let's be honest, libGDX doesn't play well with HTML. But, if you are like me, you want to be a completionist and force it to work. Well, be forewarned: you will have to deal with a lot of code workarounds in order to make your application compile to HTML. For the time being, though, let's just look at how to actually get it to compile.

In Android Studio, open the Gradle window by clicking the vertical 'Gradle' button on the right side. In that menu, expand ':html', then expand 'other', and finally click on 'dist'. That will build your web app.

To find the files, you need to go into:
[APPLICATION PATH]/html/build/dist
All of the files will be in that folder and its subfolders.

A word of warning, though. Even with the default libGDX app (showing a picture on a red background), it doesn't seem to work in every browser. For example, on my Linux machine, it works fine on Seamonkey (2.49.1) but not on Chrome (63.0.3239.132). At some point in the future I might come back to figure out why, but for the time being I am going to accept that it compiles and leave it at that.

Wednesday, May 9, 2018

Setting up a libGDX project in Android Studio

***** This tutorial is based on the libGDX tutorial series at Game from Scratch. Their tutorial is helpful, but outdated, so I am going through and updating it based on Android Studio 3.0.1 and libGDX 1.9.8 *****

Before we start, please understand that I am only one person and I am going through this tutorial for my own benefit. Because of that, I won't be able to cover all instances exactly. Particularly, I use a crummy old Linux laptop for coding and don't have access to either a Windows or Mac machine to test how things work on other operating systems. Where possible I will try to provide help, but since I won't be able to test it, I can't make any guarantees.

The first step is to ensure that you have Android Studio and the Java Development Kit (if you have trouble, make sure you installed the 'JDK' specifically).

Next, download the libGDX project setup tool and put it in a convenient directory. (Note there is an official setup guide, although it, too, is a bit out of date.) Now that you have all the necessary files, let's get started on importing a project.

1. From the command line, go to the directory where you saved the libGDX setup file (gdx-setup.jar) and type:

java -jar gdx-setup.jar


You should see this screen now:

If you don't, the most likely issues are that you are not in the correct directory or that you haven't installed the Java JDK. Recheck those steps before doing anything drastic.

2. Now it is time to set up the project. 
  • First, choose the name that you want to use. I will call my project Dot's Dots, but feel free to call your project whatever you like. 
  • For the Package name, I follow the Google Play naming convention, so will use com.petenotpete.dotsdots.
  • Game class isn't overly important, but I will also change it to DotsDots because I like to be thorough.
  • Destination is fairly important for ease of use. I want to create the project in the same folder as the rest of my Android Studio projects just for convenience sake. If you do this, you should specify the actual folder of the project, and not the generic projects folders. For example, in my case you would want to specify:
    /home/netbook/AndroidStudioProjects/dotsdots
    If you don't know where that is, or don't care, just save the project somewhere convenient for you.
  • Android SDK location is obviously important, but it should be automatically filled in. If for some reason it isn't, you can find the location of the SDK by opening an Android Studio project and selecting 'File' -> 'Other Settings' -> 'Default Project Structure...'
  • For the subprojects, I just leave the default. We will discuss a bit about web based and desktop applications, so they are good to have, and who knows, you might just want to publish your app to the App Store some day.
  • Under extensions, I just leave the default 'Box2d' checked.
3. Now that everything is filled out properly, click that 'Generate' button. When I do this I get two warnings:



In both cases I hit 'No'. I am not sure how things will work otherwise, but I read of some fairly recent (as of early 2018) issues on Stack Overflow where the libGDX project wasn't compiling because it didn't work with the newest Android and Gradle versions so figure it is better to stick with the recommended versions.

Once that is done, go get yourself a cup of coffee and watch everything get set up.

4. Once the libGDX project generator says it is finished, open up Android Studio and open the project.  Sometimes it doesn't show up in the menu immediately, but if you browse the directory structure you should be able to find and open the project.

5. When you open the project in Android Studio, it is likely you will get a popup similar to the following:

It honestly doesn't matter that much what you pick because we are going to have to change the Gradle version again anyway, but I personally select "Don't remind me again for this project" because otherwise you get an error immediately upon opening.

6. So now you should have the project open in Android Studio, and the next step is going to be getting the project to compile on desktop, HTML and Android.

Saturday, May 5, 2018

Using LibGDX with Android Studio

All of my previous apps I had designed just using Java directly in Android Studio, but my ambitions have been growing and I decided that I need to use some sort of game engine to continue developing what I want. The problem is that there are so many game engines available for Android development. Seriously, go Google it (ok, you probably already have if you are reading this), I will wait.

I realize that none of the game engines are perfect, and choosing one would involve trade offs. In order to find the best game engine for me, I made a short list of must haves and preferences. I ended up with three musts:

1. Open source and free to use - I am not making any money here, well not anything to speak of, and I prefer to minimize any possible expenses.
2. Strong 2d engine - I don't foresee myself making any 3d games in the near future, so I prefer a game engine that focuses on 2d as it suits my needs.
3. Extensive documentation - I am not an expert and am doing this as a hobby, so I need to find a well developed engine that has a lot of tutorials available.

On top of this, I would prefer a game engine that uses Java so that I don't have to completely relearn everything. This isn't incredibly important, but I have limited time and would prefer not to use that trying to understand a new language.

Anyway, after some research, I had two game engines that I was interested in, Godot and libGDX. They both hit my three must haves, and it was hard for me to choose between the two. Originally I was going to go with Godot, but after a quick Googling it looked like libGDX had been around longer and had much more written in terms of tutorials and beginner's help.

While this was true, it turned out to not be that much of a blessing. Most of the tutorials and walkthroughs for libGDX are outdated and don't work with the current version, which has been causing me headaches. HOWEVER! I actually think this might be a good thing, because instead of being able to just copy and paste the code that I want, I have to go through and figure everything out. This is going to help me in the long run, and it will definitely make me a better developer.

At the same time, I understand that not everyone wants to go through the trouble, so I am going to do my best to chronicle my progress here so that people going forward can have an up to date walkthrough on how to get started.