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:

wonder

Expert
Licensed User
Longtime User
John Guillory
00:00 (20 hours ago)

The update works fine!

Just to confirm the the new update (v1.12) does work with ARM 64bit.
Thank you, once again!
 
Last edited:

ilan

Expert
Licensed User
Longtime User
hi

i have a question related to Box2d but i can't find a main thread about box2d so i will ask my question here

i am creating a body of an enemy (its a flying bird)
the body shape is a lgBox2DChainShape so i can create concave polygon.
everything works fine.

but i have a small problem

my bird has 2 limits in the x coordinate
i want it when it reaches limit b then it will fly to limit a
the problem is that the shape of the body will give me the right collision only if it is flying to the right but when it is flying to the left the body and animation doesnot match

so i am now thinking of how to solve this problem. i could create 2 lgBox2DFixtureDef and when the bird flies to to the left change his lgBox2DFixtureDef
but i was wondering if such function like Flip body shape exist in box2d? this will save me a lot work.

i am attaching an image that will explain my issue

thanx for your help

 

Informatix

Expert
Licensed User
Longtime User
Look at Box2D_PhysicsBodyEditorLoader demo. Usually, it's the body that defines the orientation of the sprite and not the contrary (MySprite.Rotation = MyBody.Angle * Conversion.radiansToDegrees).
 

ilan

Expert
Licensed User
Longtime User
Look at Box2D_PhysicsBodyEditorLoader demo. Usually, it's the body that defines the orientation of the sprite and not the contrary (MySprite.Rotation = MyBody.Angle * Conversion.radiansToDegrees).

sorry but i dont understand. rotating the body wont give me much. i need more to flip it Vertices (its a chain body)

or have i understood your answer wrong?
 

ilan

Expert
Licensed User
Longtime User
Oh yes you're right. I read you a bit too quickly.
There's no easy way to do that. You have to create a new body with the vertices translated on the x axis.
To create your bodies, you should use the Physics Body Editor if it's not already the case.

so you suggest create a body and when body reach limit a destroy it and create a new body? i was thinking of the same but i thought there would be a way
where i could create 2 shapes and attached them to the body without destroy it.

EDIT: i mean hold a reference for each shape and attach it to the body according to the side he is flying (not attach both at once )
 

Informatix

Expert
Licensed User
Longtime User
Having two different fixtures (with one of them attached to an unique body) or two distinct bodies depends on what's convenient in your game. I have no opinion about that.
 

ilan

Expert
Licensed User
Longtime User
Having two different fixtures (with one of them attached to an unique body) or two distinct bodies depends on what's convenient in your game. I have no opinion about that.


YESSSSSS i got it

B4X:
        If enemyobj.horizontal = 0 Then '0 go to right/left, 1 go up/down
            If vec2.x < enemyobj.limitA Then
                enemyobj.speed = enemyobj.speed * -1
                enemy.destroyFixture(enemy.GetFixture(0))
                Dim chainshape As lgBox2DChainShape
                chainshape.createChain(enemyobj.goleftVertices)      
                Dim chainShapeDef As lgBox2DFixtureDef
                chainShapeDef.shape = chainshape
                chainShapeDef.restitution=0
                chainShapeDef.Density = 1
                chainShapeDef.friction=0.8
                chainShapeDef.isSensor = True
                enemy.createFixture(chainShapeDef)
            else if vec2.x > enemyobj.limitB Then
                 enemyobj.speed = enemyobj.speed * -1
                enemy.destroyFixture(enemy.GetFixture(0))
                Dim chainshape As lgBox2DChainShape
                chainshape.createChain(enemyobj.gorightVertices)      
                Dim chainShapeDef As lgBox2DFixtureDef
                chainShapeDef.shape = chainshape
                chainShapeDef.restitution=0
                chainShapeDef.Density = 1
                chainShapeDef.friction=0.8
                chainShapeDef.isSensor = True
                enemy.createFixture(chainShapeDef)              
            End If  
            enemy.setLinearVelocity2(enemyobj.speed,0)  
        Else
            '....          
        End If

if am destroying fixture 1 and creating fixture 2 everything works PERFECT!!!


btw if you would like to know how to flip in X axis then i do it like this:

B4X:
            For i = 0 To polylineobj.Polyline.Vertices.Length - 1
                Dim ver As Float = polylineobj.Polyline.Vertices(i)
                rightside(i) = ver / scalex  
                If i Mod 2 = 0 Then
                    leftside(i) = (ver / scalex)* -1
                Else
                    leftside(i) = ver / scalex  
                End If                          
            Next
 
Last edited:

ilan

Expert
Licensed User
Longtime User
here is the video that demonstrate it:




been able to destroy and create new fixture without have to destroy the body is a huge advantage for example for such a scenario

i love it when everything works
 

wonder

Expert
Licensed User
Longtime User
A small remark, if I may...

I noticed that the player hitbox holds some white space...
In terms of game design, the hitbox for the player should be smaller or equal (in term of proportion) to the enemies.
This makes the game more user-friendly, it allows the player to escape "near-misses" and be more successful when shooting or hitting the AI agents.

I personally prefer it perfectly balanced, but nonetheless it's up to you to decide what's best to you game.

http://tvtropes.org/pmwiki/pmwiki.php/Main/HitboxDissonance
Some developers intentionally create this difference in collision size. The most frequent intentional use is a small player hitbox, hopefully displayed clearly so the player knows exactly what they can and can not get away with.
 

ilan

Expert
Licensed User
Longtime User

the whole reason i choosed box2d is to have a perfect collisions detection for my game and as you can see on the bird i have not create a big ellipse or rectangle.
i created a concave polygon to have a much better collision.

for the player i choosed a rectangle because the difference is minor and its simple to work with a rectangle.
dont forget that u r watching on the idle animation. the running animation covers that white space
 

wonder

Expert
Licensed User
Longtime User
@Informatix, the following function call(s) causes a crash:
B4X:
bitmapFont.GetWrappedBounds("[", 100).Height
B4X:
bitmapFont.GetWrappedBounds("[abc", 100).Height
B4X:
bitmapFont.GetWrappedBounds("abc[", 100).Height
It seems that the "[" character is the cause of the problem. I've tried to escape it ("\["), but without success.
Are you able to reproduce this issue?

B4X:
'Input String: "[12"
'
'java.lang.StringIndexOutOfBoundsException: length=3; index=3
'    at java.lang.String.charAt(Native Method)
'    at com.badlogic.gdx.graphics.g2d.BitmapFont.getBounds(SourceFile:277)
'    at com.badlogic.gdx.graphics.g2d.BitmapFont.getBounds(SourceFile:262)
'    at com.badlogic.gdx.graphics.g2d.BitmapFont.getWrappedBounds(SourceFile:385)
'    at com.badlogic.gdx.graphics.g2d.BitmapFont.getWrappedBounds(SourceFile:341)
'    at anywheresoftware.b4a.libgdx.graphics.lgBitmapFont.GetWrappedBounds(SourceFile:260)
'    at com.ninjadynamics.knights.ninjatextbox._drawtext(ninjatextbox.java:360)
'    at com.ninjadynamics.knights.ninjatextbox._draw(ninjatextbox.java:266)
'    at com.ninjadynamics.knights.main._drawtextboxes(main.java:5070)
'    at com.ninjadynamics.knights.main._ingamescreen_render(main.java:6956)
'    at java.lang.reflect.Method.invokeNative(Native Method)
'    at java.lang.reflect.Method.invoke(Method.java:511)
'    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:169)
'    at anywheresoftware.b4a.libgdx.lgScreenManager$lgScreen.render(SourceFile:125)
'    at anywheresoftware.b4a.libgdx.lgScreenManager.Render(SourceFile:75)
'    at anywheresoftware.b4a.libgdx.LibGDX$b.render(SourceFile:156)
'    at com.badlogic.gdx.backends.android.AndroidGraphics.onDrawFrame(SourceFile:449)
'    at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1514)
'    at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1238)
'java.lang.StringIndexOutOfBoundsException: length=3; index=3
'java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
'    at android.os.Handler.<init>(Handler.java:197)
'    at android.os.Handler.<init>(Handler.java:111)
'    at android.app.Dialog.<init>(Dialog.java:107)
'    at android.app.AlertDialog.<init>(AlertDialog.java:114)
'    at android.app.AlertDialog$Builder.create(AlertDialog.java:931)
'    at anywheresoftware.b4a.BA.ShowErrorMsgbox(BA.java:228)
'    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:207)
'    at anywheresoftware.b4a.libgdx.lgScreenManager$lgScreen.render(SourceFile:125)
'    at anywheresoftware.b4a.libgdx.lgScreenManager.Render(SourceFile:75)
'    at anywheresoftware.b4a.libgdx.LibGDX$b.render(SourceFile:156)
'    at com.badlogic.gdx.backends.android.AndroidGraphics.onDrawFrame(SourceFile:449)
'    at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1514)
'    at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1238)

It's not a big deal for my project (annoying at best) but nonetheless, please have a look if you have some time.
 
Last edited:

Informatix

Expert
Licensed User
Longtime User
Set MarkupEnabled to False. [ is a reserved character when MarkupEnabled is set to True (look at the BitmapFont demo to see how to set colors with []).
 

ilan

Expert
Licensed User
Longtime User
hi everybody,

does anyone know how i could make an loading animation for a button?

i have a button that clicking on it will fire a sword now there is a reload time (45 frames) now instead of drawing the button immediately with his original color
i would like to draw it black/white (or grey white) and just calculate 360/45 frames and for each frame draw only the angle from the center of the button with the button color until 45 frames are over and the button has full color.

(sorry for my english) i will draw what i mean. (it should be a loading animation for the button until the reload count down is again 0)




EDIT: with button i mean just a simple lgtexture!
 
Last edited:

wonder

Expert
Licensed User
Longtime User
Hi!

The ImmersiveMode works perfectly with lGdx.Initialize2() but when using lGdx.InitializeView2() the immersive mode does work, but I get a gray bar at the bottom.

EDIT: I see that 100%y is not updated, even after using this code at Activity_Create:
B4X:
Dim jo As JavaObject = Activity
jo.RunMethod("setSystemUiVisibility", Array As Object(5894))

Any way to fix this?
 
Cookies are required to use this site. You must accept them to continue using the site. Learn more…