LWJGL Entities

By the end of this tutorial you will have learned how to leverage the power of object-oriented programming to create a game engine containing game entities.

The story behind LWJGL entities

Instead of looking at the scene as a bunch of shapes, look at the scene as a bunch of objects. Each object has material properties, a bounding box for collision and an amount of transparency for instance. Furthermore, each object can be classified into more abstract groups or categories. For example: a football (or soccer ball), a basketball, and a tennis ball are all balls. They all share the same properties of a ball, being round, but they also differ. Utilising this approach makes managing an object pool straightforward.

LWJGL Entity interface

This is the parent interface for the entity.

public interface Entity2D {
	public float getX();
	public float getY();
        public void setX(float x);
        public void setY(float y);
        public void setLocation(float x, float y);
	public void setUp();
	public void destroy();
	public void draw();
}

It is still very basic and generic. Collision detection would be too specific to add here. It would be better to add a CollidableEntity2D down the line.

Abstract classes – being lazy

When a lazy approach is desired, create an abstract class for the aforementioned interface and implement the position methods and leave the remaining methods abstract.

public abstract class AbstractEntity2D implements Entity2D {
	protected float x;
	protected float y;
	public float getX() { return x; }
	public float getY() { return y; }
        public void setX(float x) { this.x = x; }
        public void setY(float y) { this.y = y; }
        public void setLocation(float x, float y) {
    		this.x = x;
    		this.y = y;
        }
	public abstract void setUp();
	public abstract void destroy();
	public abstract void draw();
}

Implementing the interface fully

It is now possible to easily create a class derived from the ‘Entity2D’ interface.

public class Box2D extends AbstractEntity2D {
	protected float size;
	public Box2D(float x, float y, float size) {
		this.x = x;
		this.y = y;
		this.size = size;
	}
	public Box2D() {
		this.x = this.y = this.size = 0;
	}
	@Override
	public void setUp() {
		// We don't need anything here for a box
	}
	@Override
	public void destroy() {
		// We don't need anything here for a box
	}
	@Override 
	public void draw() {
		glBegin(GL_TRIANGLES);
		glVertex2f(x + size/2, y + size/2);
		glVertex2f(x + size/2, y - size/2);
		glVertex2f(x - size/2, y - size/2);
		glVertex2f(x - size/2, y - size/2);
		glVertex2f(x - size/2, y + size/2);
		glVertex2f(x + size/2, y + size/2);
		glEnd();
	}
}

Using the classes for the LWJGL Entities in code

To create an instance of ‘Entity2D’, write the following code.

// Before game loop
Entity2D box = new Box2D(30.0f, 50.0f, 25.0f);
box.setUp();
// In game loop 
box.draw();
// After game loop
box.destroy();

Note that even though the ‘setUp()’ and ‘destroy()’ methods do not appear necessary, they are still called. The reason is that in the future resource handling might be put there.

Conclusion

This concludes this tutorial. Should you have any questions or remarks, I would love to see them in the comments section below.

20 thoughts on “LWJGL Entities

    1. Anonymous

      In programming, “lazy” is not always a negative thing, it often means writing cleaner code that takes less time to run.

      Reply
  1. Griffin

    Can you procedurally generate these entities at the games will or do you have manually type the constructor for each entity. Eg. Naturally spawning animals that have another entity created when the random class picks 1/10.

    Reply
        1. Sam

          Griffin, you would implement it something like this:

          // All the randomly added entities in your game.
          private static final ArrayList entities = new ArrayList();

          // How many entities should be present at once?
          private static final int numEntities = 60;

          // Initialize your game.

          // Run in another thread, as usual.
          private void gameLoop() {
          while(running) {
          // Loop through entities, moving them and drawing them, and remove an entity if it’s no longer used–call addEntities().
          }
          }

          private void addEntities() {
          while(entities.size() < numEntities) {
          if(Math.random() < 70) // 70% chance.
          entities.add(new Zombie());
          else // Other 30%.
          entities.add(new Pig());
          // And so forth.
          }
          }

          Reply
    1. R@

      If you are asking for a way to create and control a potentially infinite amount of objects, I think you must use a Data Structure to store and iterate through them. For example:
      HashTable() allows quick reference to specific objects using a key.
      ArrayList() is great to iterate through same-class objects when you need to update all of them in some way.
      BinaryHeap() is an useful asset when you wish to iterate orderly through some property common to a series of objects.
      I’m sure you can think of some Data Structure that comes handy in your case.

      Reply
    1. Anonymous

      When you implement an interface you have to declare all the methods,but with an abstractclass you only have to subclass and override the desired methods. Lazyness ftw!

      Reply
    2. Sam

      When he said lazy, he did not mean for it to be taken so seriously. In general, the rule is that a lazy programmer creates the simplest and thus most efficient programs. Abstract classes (think “Ball”) define a set of characteristics common to all subclasses (like “Football”, “Baseball”, and “Basketball”). Thus, you don’t have to rewrite all the variables in each individual class (the hard way). Technically, neither of the two ways is any faster than the other, simply because the compiler breaks the code down the same as the hard way if you do it the easier, smarter way. HOWEVER–abstract classes are very important for things such as lists of randomly generated entities. In the comments above, you can find my example, where you might add multiple types of entities to a list. If you have an ArrayList, you can’t add Baseballs lot it–same as the other way around. But if you make an ArrayList, you can randomly add Footballs, Baseballs, Etc. to the same list.

      Reply

Leave a Reply to Sam Cancel reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>