B4J Library SimpleGameEngine

This is a game framework for B4J that includes many features of advanced game frameworks like libGDX but is designed to be as simple to use as possible.
It can be used for games of course, but also for animations, slideshows, paint program, etc. It is more complete than the Canvas library.

This framework has been entirely written from scratch (except 20-30 lines taken from libGDX for the most technical parts of the tiled map reader). The Java source code is available against a donation of 10 euros or more.

Don't miss this game made with SGE (PacDroid, a Pacman clone):
https://www.b4x.com/android/forum/threads/pacdroid.78617/

Let me know if you are using this library for a real project. And, of course, feel free to post comments and suggestions.

Actors:
sgeActor
sgeGroup
sgeRootGroup

Audio:
sgeMusic
sgeSound

Automation:
sgeAction
sgeActions
sgeInterpolators

Camera:
sgeCamera

Drawing:
sgeGraphics

Effects:
sgeEffect...

Input:
sgeInput
sgeKeyEvent

Geometry:
sgeBoundingBox
sgeCircle
sgeIntersections
sgePoint2D
sgePolygon
sgeSegment
sgeSpline

Maps:
sgeMapCell
sgeMapTile
sgeMapTileset
sgeTiledMap
sgeTiledMapImageLayer
sgeTiledMapObject
sgeTiledMapObjectLayer
sgeTiledMapTileLayer

Navigation:
sgeNavigationGrid
sgeNavigatorAStar

Steering behaviors:
sgeBehavior
sgeBehaviorFollowPath
sgeBehaviors
sgeVehicle

Visual objects:
sgeAnimation
sgeNinePatch
sgePath
sgeRegion
sgeText

Miscellaneous:
sgeAssetManager
sgeScreen
sgeUtils

Current version : 1.61
Search tags: Simple Game Engine, jSimpleGameEngine
 

Attachments

  • SGE_examples1.zip
    203.3 KB · Views: 571
  • SGE_examples2.zip
    477.3 KB · Views: 405
  • SGE_examples3.zip
    423.6 KB · Views: 428
  • SimpleGameEngine161.zip
    216.9 KB · Views: 431
Last edited:

Informatix

Expert
Licensed User
Longtime User
I tried it on b4j v 5.51, SGE v 1.0 and all above examples working fine here.

But small "bug" in the DirectConnections example, if I click on the "start" position example crashes.
B4X:
Loading 0% IMAGE "Level" level.png
Loading 50% GRID "NavigGrid" navigrid.txt
main._sge_render (java line: 202)
java.lang.NullPointerException
    at b4j.example.main._sge_render(main.java:202)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:90)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:77)
    at flm.b4j.simplegameengine.SGE$1.handle(SourceFile:134)
    at javafx.animation.AnimationTimer$AnimationTimerReceiver.lambda$handle$484(AnimationTimer.java:57)
    at java.security.AccessController.doPrivileged(Native Method)
    at javafx.animation.AnimationTimer$AnimationTimerReceiver.handle(AnimationTimer.java:56)
    at com.sun.scenario.animation.AbstractMasterTimer.timePulseImpl(AbstractMasterTimer.java:357)
    at com.sun.scenario.animation.AbstractMasterTimer$MainLoop.run(AbstractMasterTimer.java:267)
    at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:506)
    at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:490)
    at com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$404(QuantumToolkit.java:319)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
    at java.lang.Thread.run(Thread.java:748)
This is not due to the library but to the demo. I didn't protect the particular case where you want to find the exit while being already at the exit. In this case, the algorithm returns Null for Waypoints and the demo code crashes because it cannot handle Null.
 

Informatix

Expert
Licensed User
Longtime User
Here's how to load assets with Wait For (requires B4J v5.5+):
B4X:
AM.Add(AssetType, UniqueName, Folder, FileName)
AM.Add(...)
AM.LoadAllAssets OR AM.LoadThisAsset(AssetType, UniqueName)
Wait For AM_Loaded
That may be useful in some cases as the Loaded event does not return details.
That does not prevent the Loading event sub from being called as usual before loading an asset. Note that there's no obvious interest to use Wait For for the Loading event, especially with numerous assets.
 
Last edited:

Informatix

Expert
Licensed User
Longtime User
Maybe some users of this library are surprised by the lack of mouse events for the actors and groups of SGE, contrary to their counterpart in LibGdx. There's only a sgeInput class to detect all events at the SGE level. It's by design. You're invited to use another approach for the handling of mouse events.
Traditionally, you have a dispatching function in the library code that tries to find which object currently on screen is concerned by the mouse event, then raises the event for this object (with the risk of targeting the wrong object because rules may apply that are specific to your game). In SGE, you have to detect yourself the right object. For example, if you want to detect only visible groups, this code will get you all groups under the mouse position, orderer by Z-order (the topmost being the first):
B4X:
Sub SGE_MousePressed(EventData As MouseEvent)
    Dim MouseClick As sgePoint2D = SGE.Input.MouseToCanvas(EventData.X, EventData.Y)
    Dim ClickedList As List = SGE.Root.FindAtPos2(MouseClick, SGE.Root.FIND_ONLY_GROUPS, True)
    Dim ClickedGroup As sgeGroup
    If ClickedList.Size > 0 Then
        ClickedGroup = ClickedList.Get(0)
    End If
    If ClickedGroup.IsInitialized Then
        'There's a group found under the mouse. Your program can call the appropriate function to handle this event.
    ...
End Sub
Imagine that you want to prevent a great number of groups and actors from receiving events at a given time (because the player has not found yet the sword of light to slash monsters with furious mouse clicks, or because you want to display some kind of modal dialog, etc.), the usual approach is to add a restriction in the event handlers of all objects (something like "if not concerned then return"). Problem: it's hard to maintain in a complex project. You should consider that the event handler specific to actors or groups always receives a valid event and has to deal with. It means that all restrictions have to be handled by your dispatching code. For example:
B4X:
    ...
    If ClickedGroup.IsInitialized Then
        'There's a group found under the mouse. Your program can call the appropriate function to handle this event.
        If MyModalDialogIsDisplayed = True Then
            'My modal dialog has a button and, of course, the player is allowed to interact with it. Not with the other objects on screen.
            'The class that created the button and handles clicks on it is stored in the Tag property.
            if ClickedGroup.Tag is clsDialogButton then
                Dim Button As clsDialogButton = ClickedGroup.Tag
                Button.MousePressed(EventData)
            Else
                Return
            End if
        End if
        ...
    End if
End Sub
In the above example, you see that you don't have to write "If MyModalDialogIsDisplayed = True Then Return" everywhere, or to add an invisible object to block events like I saw in many apps. Moreover, all rules are in a single place. In my current game, I just had to add three lines of code in my dispatcher to avoid handling events when some animations are in progress, and only one line for the paused state ("If Paused Then Return", and exactly the same line in SGE_Update to freeze everything).
 
Last edited:

Informatix

Expert
Licensed User
Longtime User
Here are a few screenshots of the UI Elements demo included with the new version of SGE:

holo.jpg
robot.jpg
xp.jpg


And a screenshot of what you get with the new sgeGroup.DebugDraw function:

debug.jpg


Actors = Yellow, Groups = Magenta
 

Informatix

Expert
Licensed User
Longtime User
About the 9-patch support in v1.3:
A 9-patch PNG image used under Android has two areas: the scalable area (defined by the black lines at the top and left) and the content area (defined by the black lines at the bottom and right). The content area is not supported by SGE for now.
 

ilan

Expert
Licensed User
Longtime User
hi @Informatix, any chance SGE will support gamepads?

i saw that you mentioned already about a missing USB lib for b4j but sorry for my silly question.
if my keyboard that is connected via USB i can catch all button clicks why can't i do the same with a connected Joystick? :confused:
 

Informatix

Expert
Licensed User
Longtime User
hi @Informatix, any chance SGE will support gamepads?

i saw that you mentioned already about a missing USB lib for b4j but sorry for my silly question.
if my keyboard that is connected via USB i can catch all button clicks why can't i do the same with a connected Joystick? :confused:
I would really like to have a gamepad support in SGE, but there's no mean to read the gamepad data with JavaFX. A gamepad is not a keyboard nor a mouse; it has its own messages. Since nobody implemented the communication with the device in JavaFX, there's no event, no listener, nothing. And I don't want to write an USB library. Not enough time.
 

ilan

Expert
Licensed User
Longtime User
implemented the communication with the device in JavaFX, there's no event, no listener, nothing

oh ok i understand.
so if there would be a USB lib it will be able to listen to any attached Hardware?

i see lot of emulators or games where you can configure your controls to use any button. it also works with gamepads and i would like to implement something like this in my b4j game. i just bought me a joystick for tests and i tried it with "MyNes" (its a NES emulator) and it works great but i guess i will need to wait until a java genius will wrap a b4j lib for us :)
 
Top