B4J Library jLibGDXemulator - The easiest way to port your B4A LibGDX games

jLibGDXemulator
Work In Progress [Open Source]


dual.jpg

B4J vs B4A

Have you created a game in B4A using LibGDX? Wouldn't it be awesome if you could just copy-paste your code from B4A into B4J and have it work?
Well, look no further! The future is here! :D

Instructions:
1. Download both jLibGDXemulator and jGameViewHelper libraries and extract the files into your B4J libraries folder.
2. Include the jLibGDXemulator library in your project.
3. Add the LibGDX.bas module to your project.

Remember: jGameViewHelper is required to be in your libs folder.

In order to have B4J understanding the [B]Informatix[B]'s[/B][/B] B4A LibGDX syntax, I've created a sort of emulator, using [B]Erel's[/B] excellent B4J GameView lib.
Below, a B4J (left) and B4A (right) sprite animation example running side-by-side using exactly the same LibGDX code. Ok, 99% the same code...



So far, only a few basic LibGDX functions have been "ported" so don't expect any complex operations such as collision detection. This project is mainly focused in emulating the rendering part.

Remember: jGameViewHelper is required to be in your libs folder.

B4A Example:
B4X:
'B4A Code
'=================================================
    #Region  Project Attributes
        #ApplicationLabel: LibGDX Test
        #VersionCode: 1
        #VersionName: 1
        'SupportedOrientations possible values: unspecified, landscape or portrait.
        #SupportedOrientations: Landscape
        #CanInstallToExternalStorage: True
    #End Region

    #Region  Activity Attributes
        #FullScreen: True
        #IncludeTitle: False
    #End Region
'=================================================

'B4J Code
'=================================================
'    #Region  Project Attributes
'        #MainFormWidth: 600
'        #MainFormHeight: 400
'    #End Region
'=================================================

Sub Process_Globals
    'Common
        Type Sprite(Texture As lgTexture, TextureRegion As lgTextureRegion, ActiveFrame As Int, ActiveFrameX As Int, ActiveFrameY As Int, Rows As Int, FPS As Int, TimeStamp As Long)

    'B4J Code
    '=================================================
'        'Standard B4J stuff
'            Dim fx              As JFX
'            Dim MainForm        As Form
'
'        'LibGDX
'            Dim GLView          As View
'            Dim lGdx            As LibGDX
'            Dim Gl              As lgGL
'            Dim Camera          As lgOrthographicCamera
'            Dim Batch           As lgSpriteBatch
'            Dim Ryu             As Sprite
    '=================================================
End Sub

'B4J Code
'==========================================================
'Sub AppStart (Form1 As Form, Args() As String)
'    'MainForm Settings
'        MainForm = Form1
'        MainForm.SetFormStyle("UNIFIED")
'        MainForm.RootPane.LoadLayout("test") 'Load the layout file.
'        MainForm.Show
'
'    'Initialize the LibGDX layer
'        lGdx.Initialize
'End Sub
'==========================================================

'B4A Code
'==========================================================
    Sub Globals
        Dim GLView          As View
        Dim lGdx            As LibGDX
        Dim Gl              As lgGL
        Dim Camera          As lgOrthographicCamera
        Dim Batch           As lgSpriteBatch
        Dim Ryu             As Sprite
    End Sub

    Sub Activity_Create(FirstTime As Boolean)
        'Do not forget to load the layout file created with the visual designer. For example:
            Activity.LoadLayout("Layout1")

        'Initialize the LibGDX layer
            GLView = lGdx.InitializeView("LG")
            Activity.AddView(GLView, 0%x, 0%y, 100%x, 100%y)
    End Sub

    Sub Activity_Resume
        If lGdx.IsInitialized Then lGdx.Resume
    End Sub

    Sub Activity_Pause(UserClosed As Boolean)
        If lGdx.IsInitialized Then lGdx.Pause
    End Sub
'==========================================================

Sub LG_Create
    'B4J Code:
'        Batch.Initialize(lGdx.lgCanvas)
    'B4A Code:
        Batch.Initialize
    'Common
        Dim Texture As lgTexture
        Dim TextureRegion As lgTextureRegion
        Texture.Initialize("ryu.png")
        TextureRegion.InitializeWithTexture(Texture)
        Ryu.Texture       = Texture
        Ryu.TextureRegion = TextureRegion
End Sub

Sub LG_Resize(Width As Int, Height As Int)
    'Sets the camera viewport
        Camera.Initialize
        Camera.SetToOrtho2(True, lGdx.Graphics.Width, lGdx.Graphics.Height)
End Sub

Sub LG_Render
    'Clears the screen
        Gl.glClear(Gl.GL10_COLOR_BUFFER_BIT)
                 
    'Updates the matrices of the camera
        Camera.Update

    'Uses the coordinate system specified by the camera
        Batch.ProjectionMatrix = Camera.Combined

    'Sprite Animator
        Animation

    'Renderer
        Batch.Begin
        Batch.DrawRegion2(Ryu.TextureRegion, 0, 0, 300, 300)
        Batch.End
End Sub

Sub LG_Dispose
    Batch.dispose
    Ryu.Texture.dispose
End Sub

Sub LG_Pause
    LG_Resume
End Sub

Sub LG_Resume
End Sub

Sub Animation
    Ryu.FPS = 24
    If DateTime.Now - Ryu.TimeStamp > (1 / Ryu.FPS * 1000) Then
        Ryu.TimeStamp = DateTime.Now

        Ryu.Rows = 8
        Ryu.ActiveFrameX = Ryu.ActiveFrame Mod Ryu.Rows
        Ryu.ActiveFrameY = Floor(Ryu.ActiveFrame / Ryu.Rows)

        Ryu.TextureRegion.SetRegion(Ryu.ActiveFrameX * 178, _
                                    Ryu.ActiveFrameY * 178, _
                                    178, 178)
          
        Ryu.TextureRegion.Flip(False, True)
          
        Ryu.ActiveFrame = Ryu.ActiveFrame + 1
        If Ryu.ActiveFrame > 9 Then Ryu.ActiveFrame = 0
    End If
End Sub

B4J Example:
B4X:
'B4A Code
'=================================================
'    #Region  Project Attributes
'        #ApplicationLabel: LibGDX Test
'        #VersionCode: 1
'        #VersionName: 1
'        'SupportedOrientations possible values: unspecified, landscape or portrait.
'        #SupportedOrientations: Landscape
'        #CanInstallToExternalStorage: True
'    #End Region
'
'    #Region  Activity Attributes
'        #FullScreen: True
'        #IncludeTitle: False
'    #End Region
'=================================================

'B4J Code
'=================================================
    #Region  Project Attributes
        #MainFormWidth: 600
        #MainFormHeight: 400
    #End Region
'=================================================

Sub Process_Globals
    'Common
        Type Sprite(Texture As lgTexture, TextureRegion As lgTextureRegion, ActiveFrame As Int, ActiveFrameX As Int, ActiveFrameY As Int, Rows As Int, FPS As Int, TimeStamp As Long)

    'B4J Code
    '=================================================
        'Standard B4J stuff
            Dim fx              As JFX
            Dim MainForm        As Form

        'LibGDX
            Dim GLView          As View
            Dim lGdx            As LibGDX
            Dim Gl              As lgGL
            Dim Camera          As lgOrthographicCamera
            Dim Batch           As lgSpriteBatch
            Dim Ryu             As Sprite
    '=================================================
End Sub

'B4J Code
'==========================================================
Sub AppStart (Form1 As Form, Args() As String)
    'MainForm Settings
        MainForm = Form1
        MainForm.SetFormStyle("UNIFIED")
        MainForm.RootPane.LoadLayout("test") 'Load the layout file.
        MainForm.Show

    'Initialize the LibGDX layer
        lGdx.Initialize
End Sub
'==========================================================

'B4A Code
'==========================================================
'    Sub Globals
'        Dim GLView          As View
'        Dim lGdx            As LibGDX
'        Dim Gl              As lgGL
'        Dim Camera          As lgOrthographicCamera
'        Dim Batch           As lgSpriteBatch
'        Dim Ryu             As Sprite
'    End Sub
'
'    Sub Activity_Create(FirstTime As Boolean)
'        'Do not forget to load the layout file created with the visual designer. For example:
'            Activity.LoadLayout("Layout1")
'
'        'Initialize the LibGDX layer
'            GLView = lGdx.InitializeView("LG")
'            Activity.AddView(GLView, 0%x, 0%y, 100%x, 100%y)
'    End Sub
'
'    Sub Activity_Resume
'        If lGdx.IsInitialized Then lGdx.Resume
'    End Sub
'
'    Sub Activity_Pause(UserClosed As Boolean)
'        If lGdx.IsInitialized Then lGdx.Pause
'    End Sub
'==========================================================

Sub LG_Create
    'B4J Code:
        Batch.Initialize(lGdx.lgCanvas)
    'B4A Code:
'        Batch.Initialize
    'Common
        Dim Texture As lgTexture
        Dim TextureRegion As lgTextureRegion
        Texture.Initialize("ryu.png")
        TextureRegion.InitializeWithTexture(Texture)
        Ryu.Texture       = Texture
        Ryu.TextureRegion = TextureRegion
End Sub

Sub LG_Resize(Width As Int, Height As Int)
    'Sets the camera viewport
        Camera.Initialize
        Camera.SetToOrtho2(True, lGdx.Graphics.Width, lGdx.Graphics.Height)
End Sub

Sub LG_Render
    'Clears the screen
        Gl.glClear(Gl.GL10_COLOR_BUFFER_BIT)
                 
    'Updates the matrices of the camera
        Camera.Update

    'Uses the coordinate system specified by the camera
        Batch.ProjectionMatrix = Camera.Combined

    'Sprite Animator
        Animation

    'Renderer
        Batch.Begin
        Batch.DrawRegion2(Ryu.TextureRegion, 0, 0, 300, 300)
        Batch.End
End Sub

Sub LG_Dispose
    Batch.dispose
    Ryu.Texture.dispose
End Sub

Sub LG_Pause
    LG_Resume
End Sub

Sub LG_Resume
End Sub

Sub Animation
    Ryu.FPS = 24
    If DateTime.Now - Ryu.TimeStamp > (1 / Ryu.FPS * 1000) Then
        Ryu.TimeStamp = DateTime.Now

        Ryu.Rows = 8
        Ryu.ActiveFrameX = Ryu.ActiveFrame Mod Ryu.Rows
        Ryu.ActiveFrameY = Floor(Ryu.ActiveFrame / Ryu.Rows)

        Ryu.TextureRegion.SetRegion(Ryu.ActiveFrameX * 178, _
                                    Ryu.ActiveFrameY * 178, _
                                    178, 178)
          
        Ryu.TextureRegion.Flip(False, True)
          
        Ryu.ActiveFrame = Ryu.ActiveFrame + 1
        If Ryu.ActiveFrame > 9 Then Ryu.ActiveFrame = 0
    End If
End Sub

Feel free to fork or contribute to this project.
I'm looking forward to know your opinions. :)
 

Attachments

  • B4A - GDXemu Example.zip
    145.8 KB · Views: 655
  • B4J - GDXemu Example.zip
    232.7 KB · Views: 682
  • jLibGDXemulator.zip
    13.3 KB · Views: 665
  • LibGDX.bas
    1.7 KB · Views: 647
Last edited:

ilan

Expert
Licensed User
Longtime User
I don't know exactly because I did not try to estimate how much of the LibGDX code for B4A can be reused (probably 80-85%). If someone has at least 1000 euros to spend in that, I will surely have a look to it.

Ok i think 1000 euro is a fair price for such a job.

I am interested. i am sure we can get the money for that job. @wonder advised to start a crowfound for that what i think is a great idea.
if we want to get into the desktop gaming area with b4j we need to have a strong game engine that has a great physic engine in it (box2d)

@Erel also mentioned that with b4j we could make games for the Mac Store and this is something i would like to do.

i will let you know when we have the money.

thanx, ilan
 

ilan

Expert
Licensed User
Longtime User
LibGDX is basically OpenGL + Box2D (+ some more utilities and classes), packed as a user friendly bundle... I don't think JavaFX relates to it in any way...

But libgdx has also views like buttons, panels, labels,... so i think erel ask if those views are compatible with JavaFx
 

Informatix

Expert
Licensed User
Longtime User
Bad news. It's technically very complicated to render a scene into a JavaFX node with OpenGL as libGDX does (JavaFX can use OpenGL internally but you don't have a direct access). I don't think I want to delve into such troubles so I suggest to continue to use the JavaFX Canvas and 3D graphics classes (are the 3D classes wrapped for B4J?).
 
Last edited:

wonder

Expert
Licensed User
Longtime User
Top