By Using java & OpenGL, I created a basic game engine. This engine has the standard basic functionalities to be a GameEngine. The engine provides several services like basic 2d objects, cube, lighting, camera view, window object, Time, animation, load textures, transformations, basic physics and collision detection. Also, it has a MainController to control all of these components with each others.
Java is one of the best & fastest programming languages. So, no wonder to use it in Game Development. By using LWJGL (OpenGL library in java) it made the management of GPU processing to the objects more flexible.
So the question is why we should use the game engine if the OpenGL is better and faster? The answer is so simple. That's because the OpenGL hard to learn and hard to write code. The OpenGL uses built-in functions that tells the CPU what to do, and to write code from scratch is a waste of time. For this we use OOP to make it much easier. And OpenGL needs a strong understanding of Math and pyshics.
The hardest challenge I faced is that's the OpenGL is so hard to learn and the lack of good resources. during my shearching i found a book called Learn OpenGl- Grapics by joey de Vries. it's realy good and was clear.
First of all, the project must run in vs code with these extensions:
- project manager for java.
- java.
after that it needs to run the main method normally.
Window objects is for creating instance of Window class. The window is what the user can see from rendering objects. So all objects we want to see are shown in this Window.
Window(width, height, title)
window.add(GameObject); // to add an gameObject to window
window.addKeyListener(KeyListener); // Keylistener
window.addMouseListener(MouseListener); // MouseListener
window.addMouseMotionListener(MouseMotionListener);// MouseMovmentListener
window.cleanUp(); // to terminate and destroy the window
window.getBackGroundColor(); // set backgroundColor
window.getRenderingObjects(); // list of shown objects in window
window.getHeight(); // return height of window
window.getWidth(); // return width of window
window.getTitle(); // return title of window
window.getWindow(); // return id of this window
window.isRunning(); // check whatever the window still running or not (true if not running)
window.pollEvent(); // check the evnets & rerender the window
window.setCursorHidden(); // set the cursor hidden (unshown)
window.disabledCursor(); // disabled the cursor
window.render() // to render the window
lets now try our first app
import objects.Window;
import utils.Color;
public class FirstLook{
static Window window;
public static void main(String[] args) {
window= new Window(1280, 720, "First App");
window.setBackGroundColor(new Color(100,100,100));
while(!window.isRunning()){
window.render();
// our code here
window.pollEvent();
}
}
}
RESULT:
The view object is a camera view. The camera is a window to let you view the global world and its objects.
view.render() // to let the camera works
view.cameraPos() // the current position of the camera in XYZ
view.isCameraIoMovement() // check whatever the camera in IO movement mode or not
view.setCameraIoMovement(boolean); // to set if the camera in IO mode or not. IO mode mean make the camera controlled by the mouse
view.sensitivity; // vector2f for control the sensitivity of the mousein x and y axis
view.mouseSpeed; // float varible to control the mouse speed
The projection describes how the object will represent in the view. Also it's the ratio of the width and the hieght of the window.
Projection((float)width/(float)height)
Second App
import objects.Window;
import objects.View;
import objects.Projection;
import Engine.EngineController;
import objects.Rectangle;
import utils.Color;
public class SecondApp{
static Window window;
public static void main(String[] args) {
window= new Window(1280, 720, "First App");
window.setBackGroundColor(new Color(100,100,100));
View camera =new View();
Projection projection = new Projection(1280.f/720.f);
Rectangle rect = new Rectangle();
while(!window.isRunning()){
window.render();
EngineController.useDefualtProgram();
rect.draw();
camera.render();
projection.sendMatrix();
window.pollEvent();
}
}
}
RESULT
GameObject is the parent of all objects witch could be render in the window.
gameObject.collision; // collision border of this object, its equal null by defualt
gameObject.color; // to control the color of the object
gameObject.name; // object name
gameObject.physics; // this property for control the physics effect to the object (gravity, forces, movmentSpeed)
gameObject.transform; // the trnaformation of the object (scale, position, rotation, size)
gameObject.draw(); // to draw the object in the screen
gameObject.display(); // to check whatever the object are shown or not
gameObject.setDisplay(false); // to set the visablity of the object
gameObject.enableLight(); // enable the lighting on this objec ? works only on 3D objects
gameObject.loadTexture(); // to load texture foe the object (string , Texture2D)
GameObject.create(gameobject); // This static method to make reference for MainController
//to controll this object, this operation allow to control objects physics and objects collision between all objects.
Input class allow you to use IO inputs from keybaord and mouse. It take a GLFW keys as parameter
Input.getKeyDown();
Input.getKeyUp();
Input.getMouseButtonDown();
Input.getMouseButtonUp();
Input.getMouse();
Time input is imporatant in Game Egnines for several functionalities. such as animation, delay , counte or even a timer. the Time object store the current time in seconds.
Time time = new Time();
Time methods
time.retart() // reset timer. take the new initial time
time.getTime() // return the time in second
time.setTimer(t) // to set a timer
Time.deltaTime() // static method to return the current time
Transform is the tranformation of object from scaling, position and rotation. This class contains 4 main Vectors scale , position, rotation and size.
Color is an class contains 3 values RGB, range of the RGB color from 1 to 255
Color(RED, GREEN, BLUE);
Color(RED, GREEN, BLUE, ALPHA);
The collision class allow you to create collision border. in addition, it detect the collision
Collision(Vector3f size);
CheckCollision(GameObject one, GameObject two) ;
CheckXCollision(GameObject one, GameObject two) ;
CheckRightCollision(GameObject one, GameObject two) ;
CheckLeftCollision(GameObject one, GameObject two) ;
CheckYCollision(GameObject one, GameObject two);
CheckBottomCollision(GameObject one, GameObject two)
import objects.Window;
import objects.View;
import objects.Projection;
import org.joml.Vector3f;
import Engine.EngineController;
import objects.Rectangle;
import objects.GameObject;
import utils.Color;
import utils.Time;
public class RoationApp {
static Window window;
public static void main(String[] args) {
window= new Window(1280, 720, "First App");
window.setBackGroundColor(new Color(100,100,100));
EngineController.initMainWindow(window);
// to tell the engine what window will be working
View camera =new View();
Projection projection = new Projection(1280.f/720.f);
Rectangle rect = new Rectangle();
Rectangle rect2 = new Rectangle();
rect2.transform.position.z = -1;
rect2.transform.position.x = 1f;
rect.color = new Color(0,0,255);
rect2.color = new Color(0,255,0);
GameObject.create(rect);
GameObject.create(rect2);
Rectangle rect3 = (Rectangle)GameObject.create(new Rectangle());
rect3.color = new Color(255,0,0);
rect3.transform.position = new Vector3f(1,1,-2);
while(!window.isRunning()){
window.render();
EngineController.useDefualtProgram();
rect.transform.rotation.y = (float)Time.deltaTime() ;
rect2.transform.rotation.x = (float)Time.deltaTime() ;
rect3.transform.rotation.z = (float)Time.deltaTime();
camera.render();
projection.sendMatrix();
window.renderAll();
window.pollEvent();
}
}
}
output
import objects.Window;
import objects.View;
import objects.Projection;
import org.lwjgl.glfw.GLFW;
import Engine.EngineController;
import objects.Rectangle;
import objects.GameObject;
import utils.Collision;
import utils.Color;
import utils.Input;
import utils.Physics;
public class MiniGame {
static Window window;
public static void main(String[] args) {
window= new Window(1280, 720, "Game#3");
window.setBackGroundColor(new Color(60,80,200));
EngineController.initMainWindow(window);
// to tell the engine what window that it work on it
View camera =new View();
camera.cameraPos.z = 10;
Projection projection = new Projection(1280.f/720.f);
Rectangle grounds[] = new Rectangle[4];
for(int i=0; i<grounds.length; i++){
grounds[i] = (Rectangle)GameObject.create(new Rectangle());
grounds[i].transform.position.x = i;
grounds[i].collision = new Collision(grounds[i].transform.size);
grounds[i].loadTexture("assets/grass.png");
}
grounds[3].transform.position.y = 1;
Rectangle player = (Rectangle)GameObject.create(new Rectangle());
player.collision = new Collision(player.transform.size);
player.physics = new Physics();
player.loadTexture("assets/player.png");
player.transform.position.y = 2;
while(!window.isRunning()){
window.render();
EngineController.useDefualtProgram();
if(Input.getKeyDown(GLFW.GLFW_KEY_D)){
player.physics.movement = 1;
}else if (Input.getKeyDown(GLFW.GLFW_KEY_A)){
player.physics.movement = -1;
}
else{
player.physics.movement = 0;
}
if(Input.getKeyDown(GLFW.GLFW_KEY_SPACE)&& player.physics.onGround){
player.physics.jumb();
}
camera.cameraPos.x = player.transform.position.x;
camera.render();
window.renderAll();
projection.sendMatrix();
window.pollEvent();
}
}
}
output