Crossplatform game engine in Java & OpenGLES. Designed for 2D, low-fi graphics, but is capable of 3D perspective rendering for "2.5D" projects. Builds for Mac/Linux/Windows and Android.
Games are programmed against an Entity Component System, the components used by the game depend on a set of engine systems. While systems can be added arbitarily to G2Dj, there are a few that are present out of the box:
- 3D Forward Renderer
- Resource managers for shaders, textures, models
- Supports OpenGLES 2.0 standard
- Basic 2D game shaders & programmable shader interface
- Unicode Text renderer supporting the full Basic Multilingual Plane
- Tilegrid and spritesheet renderers
- Rigidbodies, colliders and trigger areas
- Colliders can be built from rectangles, circles or complex shapes made from sets of vertexes or primitives
- When Rigidbodies collide with colliders or enter trigger areas, OnCollision and OnTigger callbacks on the Rigidbody's Gameobject are invoked
- Implementation based on jbox2D
- 3D sound system based on OpenAL
- Supports wav, Ogg Vorbis, FLAC files
- 2D and 3D linear algebra
- 2-4d Vectors, Mat4x4
- Mouse
- Keyboard
- USB Gamepads
- Touchscreen handler
- Add the correct native libs for JOGL, JOAL and JInput to the project (Win32/64, Mac, Linux32/64).
- Run PreprocessorWizard.pl with #define DESKTOP
- Open the NetBeans project file and build G2Dj.
- Run PreprocessorWizard.pl with #define ANDROID
- Open the Android Studio project file and build G2Dj.
Games are written against an ECS. The ECS is comprised of 3 basic class types: Scene, GameObject, Component. Scenes define a 3D space with a customizable set of capabilities (rendering, physics, etc.). A game can be made of any number of scenes and can be run concurrently. GameObjects have a set of Components. Components define behaviours for their parent GameObjects.
public static void main(String[] args)
{
//Engine entry point
Engine.init(new Game()
{
@Override public void init(){initMyGame();}
});
}
public static void initMyGame()
{
//Load some textures
Graphics.loadFromResource("/Resources/Cloud.png");
Graphics.loadFromResource("/Resources/brick.png");
//Create a scene
WeakReference<Scene> mainScene = Engine.createScene("Main");
//Create the player game object
{
WeakReference<GameObject> aGameObject = mainScene.get().addGameObject();
aGameObject.get().setName("Player1");
Mesh aMesh = (Mesh)aGameObject.get().addComponent(Mesh.class); //add a mesh
aMesh.setTexture("_Texture", "awesome.png"); //give the mesh a texture
PlayerController aPC = (PlayerController)aGameObject.get().addComponent(PlayerController.class);
aPC.getTransform().get().setRotation(new Vector3(0,0,45));
aPC.getTransform().get().setPosition(new Vector3(0,0,+0.5f));
}
//Create the camera
{
WeakReference<GameObject> theCamera = mainScene.get().addGameObject();
theCamera.get().setName("Camera");
theCamera.get().getTransform().get().setPosition(new Vector3(-1,0,2));
theCamera.get().getTransform().get().setRotation(new Vector3(0,45,0));
theCamera.get().addComponent(CameraController.class);
theCamera.get().addComponent(Camera.class);
}
}
//Require that this GameObject's scene have 2D physics capability
@RequireSceneGraphs({Physics2DSceneGraph.class})
//Require that this GameObject have a rigidbody and a collider
@RequireComponents({Camera.class,Rigidbody.class,CircleCollider.class})
public class PlayerController extends grimhaus.com.G2Dj.Type.Engine.Component
{
private static final float s_Speed = 0.1f;
private final Vector3 inputBuffer = new Vector3();
private final Vector3 rotationBuffer = new Vector3();
private final Vector3 scaleBuffer = new Vector3();
@Override
protected void initialize() {}
@Override
protected void update()
{
//Translation
{
inputBuffer.setInPlace(0);
//Keyboard input
if (Input.getKey(KeyCode.J))
inputBuffer.x-=s_Speed;
if (Input.getKey(KeyCode.L))
inputBuffer.x+=s_Speed;
if (Input.getKey(KeyCode.I))
inputBuffer.z-=s_Speed;
if (Input.getKey(KeyCode.K))
inputBuffer.z+=s_Speed;
getTransform().get().translate(inputBuffer);
}
//Rotation
{
rotationBuffer.setInPlace(0);
//Keyboard input
if (Input.getKey(KeyCode.U))
rotationBuffer.y +=0.1f;
if (Input.getKey(KeyCode.O))
rotationBuffer.y -=0.1f;
getTransform().get().rotate(rotationBuffer);
}
//Scale
{
scaleBuffer.setInPlace(0);
if (Input.getKey(KeyCode.R))
scaleBuffer.addInPlace(0.01f);
if (Input.getKey(KeyCode.F))
scaleBuffer.addInPlace(-0.01f);
getTransform().get().scale(scaleBuffer);
}
}
@Override protected void OnComponentAdded(Component aComponent) {}
@Override protected void OnComponentRemoved(Component aComponent) {}
}
- JOGL - OpenGL support on Desktop builds
- JOAL - OpenAL
- jGLM - Reference material for Math.Mat4x4
- jbox2D - Implementation dependency for Physics2D
- JInput - Gamepad support on Desktop builds
- J-Ogg - Ogg Vorbis and FLAC decoder
- The desktop branch is setup for Netbeans
- The mobile branch is setup for Android Studio
- PreprocessorWizard.pl is used as a code preprocessor to comment out desktop and mobile specific implementation