B4A Library libGDX - Game Engine



One of the best game engines for Android is now available to B4A users. Unleash your creativity!

You can read a description of this library in this guide.

Download for B4A v10.60 and older (4 MB)
Download for B4A v10.70 and newer (4 MB)

Starting from version 1.13, the library is compiled with Java 8, and thus requires a recent version of B4A and Java 8+.
To install the library, copy the .jar file and the .xml file in your libraries folder.

This library is not compatible with the Debug mode. Ensure that you always compile in Release mode.

Download also the examples and templates.

You can reduce the weight of the library if you want to keep your APK file as small as possible. Read this post to learn how to create your Lite version.

Tutorials:
How to make games
Introduction to the libGDX library
PacDroid: from scratch to fun
Shaders

Take also a look at the Cloney Bird tutorial by andymc.

Plugins:
Box2DLights
SpecialFX

Versions:
 
Last edited by a moderator:

Informatix

Expert
Licensed User
Longtime User
You probably did not uncompress these files properly.
 

Crystal Noir

Member
Licensed User
Longtime User
What do you mean ? I've just unzipped all and open the b4a file that's all. Is there something special to do ?

Thank you in advance.


 
Last edited:

Informatix

Expert
Licensed User
Longtime User
What do you mean ? I've just unzipped all and open the b4a file that's all. Is there something special to do ?

Thank you in advance.



If the examples are unable to read their resource files, that means only two things: either these files are not at the expected location, or they are corrupted. So it seems to me that something went wrong during the uncompress/install step.
 

Crystal Noir

Member
Licensed User
Longtime User
I tried to redownload all the files twice : the lib (1.06 version), the samples. I dezipped them two times, I tried to change the directory where I dezziped them, I try all the thing and that doesn't work....When it says "installing to device", a few seconds after...crash with the same type of error 'could not find....'.

If I use the LibGDX myself with Java (Netbeans + LibGDX or Eclipse + LibGDX) the lib works perfectly with my device. So I don't understand what happens. Please apologize for my english.

B4X:
LogCat connected to: 3204ddaf8d656111
--------- beginning of /dev/log/main


--------- beginning of /dev/log/system


Copying updated assets files (63)


** Activity (main) Create, isFirst = true **


** Activity (main) Resume **
sensor listener setup
OGL renderer: Mali-400 MP
OGL vendor: ARM
OGL version: OpenGL ES 2.0
OGL extensions: GL_EXT_debug_marker GL_OES_texture_npot GL_OES_compressed_ETC1_RGB8_texture GL_OES_standard_derivatives GL_OES_EGL_image GL_OES_depth24 GL_ARM_rgba8 GL_ARM_mali_shader_binary GL_OES_depth_texture GL_OES_packed_depth_stencil GL_EXT_texture_format_BGRA8888 GL_OES_vertex_half_float GL_EXT_blend_minmax GL_OES_EGL_image_external GL_OES_EGL_sync GL_OES_rgb8_rgba8 GL_EXT_multisampled_render_to_texture GL_EXT_discard_framebuffer GL_OES_get_program_binary GL_ARM_mali_program_binary GL_EXT_shader_texture_lod GL_EXT_robustness GL_OES_depth_texture_cube_map GL_KHR_debug
framebuffer: (5, 6, 5, 0)
depthbuffer: (24)
stencilbuffer: (8)
samples: (0)
coverage sampling: (false)
Managed meshes/app: { }
Managed textures/app: { }
Managed shaders/app: { }
Managed buffers/app: { }
Error occurred on line: 55 (main)
com.badlogic.gdx.utils.GdxRuntimeException: Couldn't load file: walkanim.png
    at com.badlogic.gdx.graphics.Pixmap.<init>(SourceFile:152)
    at com.badlogic.gdx.graphics.TextureData$Factory.loadFromFile(SourceFile:110)
    at com.badlogic.gdx.graphics.GLTexture.createTextureData(SourceFile:188)
    at com.badlogic.gdx.graphics.Texture.<init>(SourceFile:114)
    at com.badlogic.gdx.graphics.Texture.<init>(SourceFile:106)
    at com.badlogic.gdx.graphics.Texture.<init>(SourceFile:102)
    at anywheresoftware.b4a.libgdx.graphics.lgTexture.Initialize(SourceFile:40)
    at flm.b4a.libgdxtest.main._lg_create(main.java:436)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:636)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:302)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:238)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:121)
    at anywheresoftware.b4a.ShellBA$1.run(ShellBA.java:66)
    at android.os.Handler.handleCallback(Handler.java:733)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:146)
    at android.app.ActivityThread.main(ActivityThread.java:5694)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107)
    at dalvik.system.NativeStart.main(Native Method)
Caused by: com.badlogic.gdx.utils.GdxRuntimeException: Error reading file: walkanim.png (Internal)
    at com.badlogic.gdx.backends.android.AndroidFileHandle.read(SourceFile:76)
    at com.badlogic.gdx.files.FileHandle.readBytes(SourceFile:256)
    at com.badlogic.gdx.graphics.Pixmap.<init>(SourceFile:149)
    ... 25 more
Caused by: java.io.FileNotFoundException: walkanim.png
    at android.content.res.AssetManager.openAsset(Native Method)
    at android.content.res.AssetManager.open(AssetManager.java:316)
    at android.content.res.AssetManager.open(AssetManager.java:290)
    at com.badlogic.gdx.backends.android.AndroidFileHandle.read(SourceFile:74)
    ... 27 more
** Activity (main) Create, isFirst = true **


** Activity (main) Resume **
sensor listener setup
OGL renderer: Mali-400 MP
OGL vendor: ARM
OGL version: OpenGL ES 2.0
OGL extensions: GL_EXT_debug_marker GL_OES_texture_npot GL_OES_compressed_ETC1_RGB8_texture GL_OES_standard_derivatives GL_OES_EGL_image GL_OES_depth24 GL_ARM_rgba8 GL_ARM_mali_shader_binary GL_OES_depth_texture GL_OES_packed_depth_stencil GL_EXT_texture_format_BGRA8888 GL_OES_vertex_half_float GL_EXT_blend_minmax GL_OES_EGL_image_external GL_OES_EGL_sync GL_OES_rgb8_rgba8 GL_EXT_multisampled_render_to_texture GL_EXT_discard_framebuffer GL_OES_get_program_binary GL_ARM_mali_program_binary GL_EXT_shader_texture_lod GL_EXT_robustness GL_OES_depth_texture_cube_map GL_KHR_debug
framebuffer: (5, 6, 5, 0)
depthbuffer: (24)
stencilbuffer: (8)
samples: (0)
coverage sampling: (false)
Managed meshes/app: { }
Managed textures/app: { }
Managed shaders/app: { }
Managed buffers/app: { }
Error occurred on line: 55 (main)
com.badlogic.gdx.utils.GdxRuntimeException: Couldn't load file: walkanim.png
    at com.badlogic.gdx.graphics.Pixmap.<init>(SourceFile:152)
    at com.badlogic.gdx.graphics.TextureData$Factory.loadFromFile(SourceFile:110)
    at com.badlogic.gdx.graphics.GLTexture.createTextureData(SourceFile:188)
    at com.badlogic.gdx.graphics.Texture.<init>(SourceFile:114)
    at com.badlogic.gdx.graphics.Texture.<init>(SourceFile:106)
    at com.badlogic.gdx.graphics.Texture.<init>(SourceFile:102)
    at anywheresoftware.b4a.libgdx.graphics.lgTexture.Initialize(SourceFile:40)
    at flm.b4a.libgdxtest.main._lg_create(main.java:436)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:636)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:302)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:238)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:121)
    at anywheresoftware.b4a.ShellBA$1.run(ShellBA.java:66)
    at android.os.Handler.handleCallback(Handler.java:733)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:146)
    at android.app.ActivityThread.main(ActivityThread.java:5694)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107)
    at dalvik.system.NativeStart.main(Native Method)
Caused by: com.badlogic.gdx.utils.GdxRuntimeException: Error reading file: walkanim.png (Internal)
    at com.badlogic.gdx.backends.android.AndroidFileHandle.read(SourceFile:76)
    at com.badlogic.gdx.files.FileHandle.readBytes(SourceFile:256)
    at com.badlogic.gdx.graphics.Pixmap.<init>(SourceFile:149)
    ... 25 more
Caused by: java.io.FileNotFoundException: walkanim.png
    at android.content.res.AssetManager.openAsset(Native Method)
    at android.content.res.AssetManager.open(AssetManager.java:316)
    at android.content.res.AssetManager.open(AssetManager.java:290)
    at com.badlogic.gdx.backends.android.AndroidFileHandle.read(SourceFile:74)
    ... 27 more
 

Informatix

Expert
Licensed User
Longtime User
Compile the Animation demo with the latest version of libGDX and B4A. The APK size should be 4 551 220 bytes. You can also open the APK file with any ZIP extractor and check whether the assets folder contains all required files with the correct name and size.
 

Crystal Noir

Member
Licensed User
Longtime User
When you say the lastest version of lilbGDX you mean the 1.06 that is on the first post ? If "yes" so I already done that (and I already have the latest version of B4A (update on saturday when I renewed my licence). But I'm going to check the APK and I will tell you the result. It's very very strange. There is something for sure but what...I will make some tests this evening and I will tell you !
 

Informatix

Expert
Licensed User
Longtime User
Yes, 1.06.
 

Crystal Noir

Member
Licensed User
Longtime User
Hi,

I 've just watched the apk file (debug mode) and there is no assets inside ! That's very strange, is there something to do for that ? (I just compile the file...). The apk is only 2 386 274
 

Crystal Noir

Member
Licensed User
Longtime User
Sorry, I didn't see it. Very sorry ! That's because I at the moment, only watch this topic just to test the lib with your example and I didn't try to code anything for now with the lib (in this case I would first read the tutorial). I think you should add this on the first topic where we download the lib and the samples in the case of someone want to test it before starting anything. In a normal case, to compile a code file, we don't need to read a tutorial, that's why I didn't think about it.

Now that's work better.

Thank you.
 
Last edited:

Informatix

Expert
Licensed User
Longtime User
I just added a warning in the first post.
 

ivavilagu

Member
Licensed User
Longtime User
I´am trying to scale a lgScn2DLabel. I have read that the transform widget group property needs to be 'True' in order to activate the action but I don´t have any widget group and I can´t see the Transform property.
 

Informatix

Expert
Licensed User
Longtime User
I´am trying to scale a lgScn2DLabel. I have read that the transform widget group property needs to be 'True' in order to activate the action but I don´t have any widget group and I can´t see the Transform property.
You have to place your label in a group to be able to rescale it, or you can use the setFontScale function or FontScaleX/FontScaleY properties.
 

Informatix

Expert
Licensed User
Longtime User
In the version 1.07, I introduced the support of the KTX/ZKTX file format. To compress your images with ETC1 and create the final ZKTX file, you can use a tool like Mali GPU Texture Compression Tool (untested) or the nightly build of the java version of libGDX with the batch attached to this post.

I noticed a strange thing with the KTX format. On my Kindle Fire HD, which runs under FireOS, the app crashes with this format when I load it directly (e.g. when initializing a texture). If I use it in an atlas, that seems to work. Under Android, on the contrary, I saw no problem at all.
EDIT: the mistery is solved. The size of the images must be a power of two. That's why the atlas pages, which observe the POT rule, were not affected.
 

Attachments

  • KTXProcessor.zip
    254 bytes · Views: 193
Last edited:

wonder

Expert
Licensed User
Longtime User
Good morning,

I'm trying to push my LibGDX based engine to its limits in order to see what can and cannot be done.
So far, excluding the background layer, I managed to have 16 animated sprites on screen. More than that will crash the application at start.
Now, I'm not saying that I need so many stuff on stage at the same time for an actual game, but I would like to understand what's going on.

Questions:
1. What's the difference between the JavaHeap and the NativeHeap? Should I worry about it?
2. Is there anything I should do regarding my rendering method in order to optimize memory usage and rendering speed?

Many thanks in advance for your help!


My rendering method:
Below, my rendering method for all actors on stage, excluding the stage itself and the HUD on the top-left corner.
B4X:
Number of ACTOR loaded textures (as lgTexture): 9
- 1x Actor Shadow
- 2x Player1 (white) (2 TexPages)
- 2x Player2 (red)   (2 TexPages)
- 2x GreenGuy        (2 TexPages)
- 2x PurpleGuy       (2 TexPages)

Number of ACTOR texture regions (as lgTextureRegion): 32
- 16x Shadows
-  1x Player1
-  1x Player2
-  7x Green Guys
-  7x Purple Guys
Following @Informatix advice on his tutorial, I'm not rendering anything that goes off screen.
B4X:
'Draw Actors and Shaddow
    If ActorOnScreen(this_actor) Then
        Batch.DrawRegion2(shaddow(this_actor), shaddow_location_x(this_actor), shaddow_location_y(this_actor), shaddow_size_x(this_actor), shaddow_size_y(this_actor))
        Batch.DrawRegion2(actor(this_actor), actor_location_x(this_actor), actor_combined_location_yz(this_actor), actor_size_x(this_actor), actor_size_y(this_actor))    
    End If


Statistics:
Using lgdx.CallSubUI in LG_Render, I've added the following lines of code:
B4X:
Sub ShowStats
    Debug.Text = "FPS: "         & lGdx.Graphics.FramesPerSecond & CRLF & _
                 "Java Heap: "   & Round2((lGdx.JavaHeap / 1024) / 1024, 3) & "MB" & CRLF & _
                 "Native Heap: " & Round2((lGdx.NativeHeap / 1024) / 1024, 3) & "MB" & CRLF & _
                 "CSAA/MSAA: "   & GDXconfig.numSamples & CRLF & _
                 "LibGDX Ver: "  & lGdx.LibGDXVersion
End Sub
Output:
- FPS: 48 ~ 52 Hz
- Java Heap: 21 ~ 23 MB
- Native Heap: 15 ~16 MB

Screenshot:
 
Last edited:

Informatix

Expert
Licensed User
Longtime User
So far, excluding the background layer, I managed to have 16 animated sprites on screen. More than that will crash the application at start.

16 is very low. You should be able to display at least 100 characters of this size on a low-cost device with a FPS > 30.

Now, I'm not saying that I need so many stuff on stage at the same time for an actual game, but I would like to understand what's going on.

Without the code, it's usually difficult to say. But one thing is certain: what makes a game fast is the choice of the right algorithms and techniques, not a trick or an optimization of the existing code. So the problem, with such a low result, lies probably more in the choices made than in the code itself.

1. What's the difference between the JavaHeap and the NativeHeap? Should I worry about it?

The Java heap is the memory reserved by the OS for each Java app. This amount is limited (from 16 MB to 128 MB depending on the device). In a shared environment, that ensures that a Java app doesn't take all memory for itself.
You allocate memory in the Java heap each time you create an object (an integer, an array, a bitmap, etc.). This heap is watched by the garbage collector so you don't have to worry about the deallocation of data in this memory space.
The native memory is the total memory of your device. A part of this memory is taken to create the Java heaps. Other languages, like C, use it natively. libGDX uses it mainly to store the texture data so you're not limited by the Java heap size for your graphical resources. The drawback is that you have no garbage collector to free resources, so you have to do it yourself with the Dispose function.

In your game, I'm surprised by the high number for the Java heap usage. In my current game, where I have a lot of data (I have big arrays and more than 300 animated sprites), I'm far under this number.

2. Is there anything I should do regarding my rendering method in order to optimize memory usage and rendering speed?

Minimize the number of texture switching by placing as many sprites as possible on the same texture with the texture packer tool. Use the ETC1 compression and the KTZ format for your opaque images. Try to reduce as much as possible the transparent parts around your sprites. Try PolygonSpriteBatch instead of SpriteBatch to see whether that improves your rendering speed. I cannot say more without any insight of your code.
With only 9 textures and 16 sprites, I don't think that the problem is in the rendering technique.

Did you time each part of your code? It's the best way to find which part takes too much time. Place each routine inside a very big loop (to smooth results over time and get an average result).

Using lgdx.CallSubUI in LG_Render, I've added the following lines of code:
Avoid calling CallSubUI. It's too slow. It should be only used to display a message box when a critical error happens. Uses a BitmapFont and a SpriteBatch to display the FPS, as I do in the libGDX examples.
 

wonder

Expert
Licensed User
Longtime User
Thank you so much for you detailed reply, Fred.

I've started this project almost one year ago, when I was taking my first steps with B4A. Most of my 2014 code is terrible, a real nightmare to look at.
My approach was very QBasic'ish, since the last time I did some coding before discovering B4A was back in 1999.

Earlier this week, I've started to clean-up the old code, I've corrected some terrible design mistakes, but I still have a lot of junk to get rid of.
Hopefully, I'll be able to reconstruct everything in a much more efficient way and lower the Java heap as much as possible.

Thank you once again for your guidance, Fred! You're an inspiration in terms of game design!
 

Informatix

Expert
Licensed User
Longtime User
I plan to publish a new tutorial before the end of this year about some advanced techniques used in my current game (and in many professional games). I will explain how I solved a few technical problems and how I'm able to run this game at 60 fps despite heavy constraints. I hope that will encourage people to do true and solid games. But as I already said, games are complex, a lot more than any traditional app, and knowing a wide bunch of algorithms (usually only available as papers written by researchers or vaguely explained in some books) is the key to become a real game developper. Just to give an idea: A*, the very famous algo for pathfinding, can be easily outperformed by algo like JPS+ if you use an uniform cost grid or by using a vector field if a lot of sprites move towards the same location. The expected gain can be much higher than 100%.
 

wonder

Expert
Licensed User
Longtime User
That's great news, I'm always up for your tutorials! Looking forward to keep learning more and more about game design.
This project has became my dearest baby, if you remember I started its development using the GameView lib.
Terrible performance back then. Once I changed to LibGDX, I couldn't believe my eyes!

I'll take your advice on getting rid of all the CallSubUI calls. I also have a lot of For/Next cycles in my logic, many of which can hopefully be merged or downsized. Let's hope for the best...

It might take me another year, but I won't give up until I have this going on the right track.
 
Cookies are required to use this site. You must accept them to continue using the site. Learn more…