Implementing component based entities

Leave a comment

In my previous blog entry about entities you saw two implementation approaches. I will go into detail with the component based method, since it is the most flexible and extendable one. As stated before I suggest to use this method to avoid issues, unless you have a very small entity hierachy.
Keep in mind that the following Entity code is designed for 2D games and that I leave out encapsulation of fields and methods due to readability and performance on some devices/OS (e.g. Android).

General aspects

  • To represent your entity you have to make an Entity class, which holds an EntityComponent array, an EntityType and basic things like the position and appearance.
  • An EntityComponent is another class and is, of course, the component itself, which has effect on the Entity.
  • EntityType is a class that holds the same information for every Entity of the same type (such as Enemy or Projectile). It can hold for example: appearance, components, name, max. speed, velocity.

 

The Entity

Entity should care about very basic things and only hold information for all entities. Let´s create a simple Entity class:

public class Entity {
	public float x = 0.0f;
	public float y = 0.0f;
	public float angle = 0.0f;
	public Sprite sprite;

	public EntityComponent[] components;
	public EntityType type;

	public boolean isDead = false;

	public Entity (EntityType type) {
		this.type = type;
		this.components = type.copyComponentList(); // We´ll look into the type later
		// Construct the Sprite here (this is another topic)
	}

	public void update () {
		int i = 0;
		while (i < components.length) {
			components[i].update(this);
			i++;
		}
	}
}

Some notes:
  • the constructor takes an EntityType as a parameter to initialize the Entity. It copies the EntityComponents of the type and creates an appearance (Sprite).
  • update() loops through the EntityComponent array to update the components.
  • isDead shows if the Entity is no longer used, so that it can be destroyed by the update loop.

Before we go on and write our first EntityComponent we will have a look at the EntityType.

 

Writing the EntityType class

An EntityType holds all information of an Entity, which type has this information in common. Imagine two EntityTypes: Enemy and Projectile. These can both be Entities, but they have a different appearance, different components, a different name and also a different speed. You can see, that storing this information in Entity would be overflow, since it is the same for maybe 100 projectiles. To avoid this we use the type.

Let´s define Enemy and Projectile (I´ll leave out the appearance):

  • Projectile:
    Components: Moveable, Projectile, Collideable
    Name: Projectile
    Speed: 200 pixel/s
  • Enemy:
    Components: Moveable, Collideable
    Name: Enemy
    Speed: 35 pixel/s

To define these types you can choose different methods. One method is to define EntityType in the code itself, another famous approach is to define all entities in files, which are loaded on startup. I´ll choose the first method, since we want to keep it simple. If you develop bigger games, the second method will be yours, because non-programmers can design entities with this method and you can implement an editor (Like the editor in Starcraft 2) to allow users to make their own entities.

So, let´s write the EntityType class:

public class EntityType {

	// The types we will use; Projectile and Enemy
	public static EntityType TYPE_PROJECTILE = new EntityType(new EntityComponent[] { new EntityComponentMoveable(200, 200), new EntityComponentCollideable(), new EntityComponentProjectile()}, "Projectile");
	public static EntityType TYPE_ENEMY = new EntityType(new EntityComponent[] { new EntityComponentMoveable(35, 35), new EntityComponentCollideable()}, "Enemy");

	public EntityComponent[] componentList; // The list that will be copied
	public String name;

	public EntityType (EntityComponent[] componentList, String name) {
		this.componentList = componentList;
		this.name = name;
	}

	// Copy the whole array
	public EntityComponent[] copyComponentList () {
		EntityComponent[] comp = new EntityComponent[componentList.length];

		int i = 0;
		while (i < comp.length) {
			comp[i] = componentList[i].copy(); // Copy it from the list
			i++;
		}

		return comp;
	}
}

This type class is, of course, very basic and leaves out any graphics related content, width and height. I will write another post about collision with those two types; We will now stick to the EntityComponentMoveable component and see how this works.

 

Finally the component

First we have to write the basic EntityComponent class. It is an abstract class, since it doesn’t do anything stand-alone.

public abstract class EntityComponent {
	public abstract void update (Entity e);
	public abstract EntityComponent copy ();
}

It just has an update(Entity e) and a copy() method, can’t be instanciated because of abstract and does not do anything. But we want to do something with those components, so let’s write the EntityComponentMoveable:

public class EntityComponentMoveable extends EntityComponent {

	public float speedX;
	public float speedY;

	public EntityComponentMoveable (float speedX, float speedY) {
		this.speedX = speedX;
		this.speedY = speedY;
	}

	@Override
	public void update(Entity e) {
		e.x += (float) Math.sin(Math.toRadian(e.angle)) * speedX * delta; // Use your delta time. It has to be in seconds.
		e.y += (float) Math.cos(Math.toRadian(e.angle)) * speedY * delta; // You should also be familiar with this formula.
	}

	public EntityComponent copy () {
		return this;
	}

}

Please note that making a new EntityComponent in the copy() method is not required, since the speed is fixed to an EntityType in this case and there is one object per type on initialisation.

And this is what happens overall:

  1. We create a type which has an EntityComponent array.
  2. When we create an Entity we pass any type to the Entity constructor and the EntityComponent array is copied.
  3. Each update the Entity updates the EntityComponentMoveable which moves the Entity based on speed.

I hope this post showed you clearly how to implement a component based entity structure. I will write more about this and my next post will be most likely about collision.

Advertisements

Plans change!

Leave a comment

My first intention was to make an RTS, but my team figured out, that this genre just doesn’t fit to us. So the project actually died in the planning phase. We are about to make another game; it is an RPG this time. The difference between the first and this project is the planning. And because we didn’t plan much for the RTS, I believe, it has died. We will see how far we get, but I’m actually very optimistic. I don’t want to announce “jobs” (not payed) here, but if you are interested in RPGs and can do anything related to sound, graphics, code or game design, you may contact me on Twitter (@marcopennekamp) and I will put you on a list. When we have worked out the concept we will come back to your offer.

Besides this change, which affects the blog directly, I think, I will post an in-depth Component tutorial soon as well as some more infos about the RPG (if my team allows me to do so 😉 ).

Entities in games and their implementation

2 Comments

Entities are the most important game elements in every game. They move, fight, trade, spawn, die, kill, look good, give quests, grant buffs and everything else you can imagine! I think you can see that a good implementation of those is essential, especially to avoid conflicts. I will show you two general implementations and will list the advantages and disadvantages. I will support everything with examples from Doodle Jump, a very famous platformer on smartphones.

 

Extention:

The first approach is very basic and seems logical. There is an Entity class, which is the basis for all Entities. It could look like:

class Entity {
  float x;
  float y;
  float z;
  void update () { ... }
  void render () { ... }
}

 

This Entity class includes the position of the entity and two methods, which are called each update from the game loop. This is very basic, so we will dive further into this in form of an example.

Doodle Jump has 4 types of entities: The player, enemies, power ups and platforms. All these entities are classes which extend Entity. Let´s have a look a the Enemy class (It is, of course, pseudo code):

class Enemy extends Entity {
  float health;
  void update () {
    move();
    if (health <= 0) die();
  }
}

 

This class adds the normal enemy functionality to the game, so you can build different enemies. It is mostly used for small games, because of it´s easy implementation.

However, this method has some disadvantages:

  • You can run into conflicts: What can you do, if you want to make an enemy, which can´t move, but moving is inherited from Enemy?
  • You will have many classes and therefore much code to maintain.

 

Component based Entities:

The second approach is conflict proove and also quite logical. Instead of having different Entity classes you have one class which has components. A component is a part of an entity, which does exactly one thing. Entities can have, of course, multiple components. Let´s have a look into the Entity class:

class Entity {
  float x;
  float y;
  float z;

  Component[] components;

  void update () {
    foreach (component in components) component.update();
  }

  void render () {
    foreach (component in components) component.render();
  }
}

 

As you can see, components are updated by the Entity every update run and their render method is also called by the Entity. You can simply add and remove components from entites. It should be clear, how the component class looks. It simply has an update and a render method and subclasses (such as Moveable) could also have variables like velocity.

In our Doodle Jump example an enemy would get the components Moveable, Enemy and Killable. Moveable gives the enemy the ability to move, Enemy declares it as an enemy to allow other entities to check for enemies and Killable gives the enemy the ability to die and also a health variable, which can be modified (e.g. by the player´s projectiles on collision).

You should prefer to use the component based method to avoid nasty conflicts. It is also better for defining entities in files and not with classes, but this is a topic for another blog entry.