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:

SSDM71

Active Member
Licensed User
Longtime User
Thanks, I see the demo but with this code it return me a runtime error:

B4X:
Sub Globals
        Dim FBO As lgFrameBuffer
        Dim FBready As Boolean = False
        Dim screen As Boolean = False
End Sub

Sub LG_Render
GL.glClearcolor(0.3,0.3,0.3,1) 'RGB,alpha - Clear screen with color based on values 0 to 1 for red, green, blue and alpha
    GL.glClear(GL.GL10_COLOR_BUFFER_BIT)
    camera.Update
    Batch.ProjectionMatrix    = camera.Combined
        If FBready Then
               RenderToFBO  
        End If
        If screen=False Then
            TakeScreenShot
        End If
        Batch.begin
        AggiornamentoImmagini 'This Sub update the images
        Batch.End
End Sub

Sub RenderToFBO
    FBO.Initialize(FBO.FORMAT_RGBA8888, lgdx.Graphics.Width, lgdx.Graphics.Height)
    FBO.Begin
        Batch.Begin
        AggiornamentoImmagini
        Batch.End
    FBO.End
    TakeScreenShot
End Sub

Sub TakeScreenShot
    If FBready=False Then
        FBready=True
    Else
        If FBO.IsInitialized Then
            Dim Pixmap As lgPixmap = FBO.GetDefaultFrameBufferPixmap(0, 0, lgdx.Graphics.Width, lgdx.Graphics.Height, True)
            Dim PixmapIO As lgPixmapIO
            PixmapIO.WritePNG(lgdx.Files.internal("screenshot.png"), Pixmap)
            Pixmap.dispose
            screen=True
            lgdx.CallSubUI("ToastMsg_Show", "Screenshot saved")
            FBready=False
            FBO.dispose
        End If
    End If
End Sub

Sub ToastMsg_Show(Text As Object)
    ToastMessageShow(Text, True)
End Sub

It give me the error at this line:
B4X:
FBO.Initialize(FBO.FORMAT_RGBA8888, lgdx.Graphics.Width, lgdx.Graphics.Height)

The error is:
B4X:
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:200)
at android.os.Handler.<init>(Handler.java:114)
at android.app.Dialog.<init>(Dialog.java:108)
at android.app.AlertDialog.<init>(AlertDialog.java:125)
at android.app.AlertDialog$Builder.create(AlertDialog.java:967)
at anywheresoftware.b4a.BA.ShowErrorMsgbox(BA.java:234)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:214)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:175)
at anywheresoftware.b4a.libgdx.LibGDX$b.render(SourceFile:136)
at com.badlogic.gdx.backends.android.AndroidGraphics.onDrawFrame(SourceFile:439)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1522)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1239)

Maybe I have to initialize the lgFrameBuffer inside LG_Create, but in the example all code works well in LG_Render

What should I do to resolve this problem?

Thanks,
 

Informatix

Expert
Licensed User
Longtime User
You did not post the right part of the error message. These error lines are common to all libGDX errors. It's the other part that gives clues.
Anyway, despite your code is a bit complicated (why do you call TakeScreenShot twice ?), I don't see any critical error. Are you sure that you run in Release mode ?
 

SSDM71

Active Member
Licensed User
Longtime User
Probably I don't understand well the lgFrameBuffer. I understand that lgFrameBuffer capture the frame and you can read the pixels inside LG_Render as follows:
B4X:
Sub LG_Render
  ClearScreen
  FBO.Begin
  WriteTheImages
  FBO.End
End Sub
It this method the lgFrameBuffer read the pixels that the sub WriteTheImages prints on the screen, and with a function i can read these pixels and put them in a pixmap,, and with lgPixmapIO write the pixmap to PNG:
B4X:
pixmap=FBO.GetDefaultFrameBufferPixmap(0, 0, lGdx.Graphics.Width, lGdx.Graphics.Height, True)
PixmapIO.WritePNG(lGdx.Files.external("screenshot.png"), Pixmap)

But I don't understand where I have to initialize the lgFrameBuffer.

Is this the right procedure to follow to take a screenshot?

Is it possible that It doesn't work because I use BOX2D?

If I compile my code in DebugMode, can it be some problems or errors?

I hope I was clear, thanks for your patience
 

Informatix

Expert
Licensed User
Longtime User
Probably I don't understand well the lgFrameBuffer.
A framebuffer is a buffer where you can render your scenes like you're used to do with the screen. Instead of being displayed, pixels are stored in memory and you can use them as a texture or copy them to a pixmap.

If I compile my code in DebugMode, can it be some problems or errors?
You cannot run your app in Debug mode because libGDX runs in a background thread. This is probably the cause of your errors.
 

SSDM71

Active Member
Licensed User
Longtime User
I have resolved this problem, I text here my error for the people that can have the same problem with the Screenshot.

My code was wrong because I used an internal path (lgdx.files.internal(path)) and inside that I can't write. Also I have wrong the position of lgFrameBuffer begin, now I put that code at bottom of LG_Render..

When It take a Screenshot I see a moment of lag. It's because FBO reads the pixels or PixmapIO that writes a PNG to external storage?
 

Informatix

Expert
Licensed User
Longtime User

wimpie3

Well-Known Member
Licensed User
Longtime User
I have a strange problem with libgdx. The number of frames my Android phone is 60fps, as it should be. However, on one other phone I have I get exactly 30fps, not more. There are no performance problems (just moving one sprite around), so there seems to be some hard coded limit somewhere in the library. Does this sound familiar to someone?
 

Informatix

Expert
Licensed User
Longtime User
Not in the library. It's a device limitation. My two chinese tablets cannot go above 50 fps.
The Google team in charge of the graphic part of Android advises to target 30 fps when you develop a game. That being said, most devices are able to display 60 fps nowadays.
 

RandomCoder

Well-Known Member
Licensed User
Longtime User
I remember reading this in one of the tutorials recently...
From here
https://www.b4x.com/android/forum/threads/how-to-make-games.32593/
However it would appear that the cap on your phone is 30fps.
 

RandomCoder

Well-Known Member
Licensed User
Longtime User
Beat me to the reply
 

wimpie3

Well-Known Member
Licensed User
Longtime User
So the next question is, how do I set the limit to 30fps? With a sleep command? An example somewhere?
 

Informatix

Expert
Licensed User
Longtime User
So the next question is, how do I set the limit to 30fps? With a sleep command? An example somewhere?
The goal is not to limit the game to 30 fps. It is to make it running fine at 30 fps. If your game does not run fine at 30 fps then there will be a problem on some devices (whatever may be the reason: slow device or device capped to 30 fps). To take into account the elapsed time between two frames and adjust all speeds of your game, read the chapter "Mind the step" in my tutorial about games. If you target 30 fps, the game should not run faster when displayed at 60 fps.
 

wimpie3

Well-Known Member
Licensed User
Longtime User
I'm using a texture atlas containing about fourty textures. However, when I do this:

B4X:
dim myGroundTexture as lgTexture=Atlas.FindRegion("ground").Texture

myGroundTexture contains the WHOLE atlas instead of just the texture of the selected region.

How can I get the texture of a certain region returned?
 

Informatix

Expert
Licensed User
Longtime User
A texture atlas is a collection of textures combined to form a single texture. That avoids switching often between textures in the GPU and eases their handling.
As the result is a single texture, you cannot "extract" the original textures from it. You have to use regions (or anything based on regions like lgSprite) to create portions of this big texture. All these regions will point to the same texture.
 

ivavilagu

Member
Licensed User
Longtime User
I have a libgdx game in advanced state so I'm testing it in some devices. In phone devices works well but what my surprised when I tried to run in a nexus 7 tablet. Backgrounds and atlas packs doesn´t display. After passing many hours looking for the problem I found that it was the resolution of pictures. Images with 3000x1500 or 1080x2500 doesn't´show in any way. If the resolution is reduced to 1920x1080 the image is displayed without problem.

Large images are about 750 Kb, not so much. I reduced the file size keeping the resolution and the problem continues, so I understand it´s not a tablet memory issue. But....

why work in phones and not in 7" tablet?
 

Informatix

Expert
Licensed User
Longtime User
The maximum size for textures under Android is 2048x2048. It's a hardware limitation. Some devices can support more but it is recommended to stick to 2048x2048.
 

ivavilagu

Member
Licensed User
Longtime User
Ups! So I need to downgrade all images and atlas pack in order to make compatible all devices.
Thanks!
 
Cookies are required to use this site. You must accept them to continue using the site. Learn more…