NcJump devlog #7


It has been a while since my last devlog, but finally I landed it. It is full of good stuff so you would not regret the wait. Let us ncJump into it!

Dying state

Definitely one of the fundamental states. Any living entity should die at some point, and this state represents that period of time where an animation should play telling the player an enemy is defeated or that the game is over. The update method of this state is super easy and it looks like that:

void DyingState::update(Entity& entity)
{
    if (entity.animation.has_finished()) {
        entity.set_enabled(false);
        // just reuse this entity for something else
    }
}

Enabled flag

Of course this explains the Entity::set_enabled() method just introduced in the previous section. By calling it, we can effectively disable an entity and all its components without destroying it, or freeing its memory, so that it could be recycled to be reused later when we, for example, need to spawn another entity.

Array of states

This was an important optimization. Before this, every state transitions triggered the destruction of the old state and creation of an instance of the new state, which is not really needed and does not scale nicely as a scene grows. Now, a state component keeps track of an array of all the possible state objects, together with a pointer telling us which one is the current state.

Initial position

Another requirement for the scene is to define where the player should start. This initial position is a pair of coordinates which tells us just this. When a scene starts, we put the player there.

Definitions and factories

I love this pattern and I think I will use from now on for all of my game projects. Basically, we have to deal with big and heavy objects which are not easily serializable. Think of wrappers around third party components like Box2D bodies or nCine sprites. I tried to find a way to serialize those objects and I believe I found a very nice solution which is anyway something widely used, so I possibly just reinvented the wheel here, but that is ok.

I do not serialize those objects. I do serialize their definitions. A definition is a collection of all the parameters needed to construct an object. Let us take a ncJump graphics component as an example.

// Very simplified
auto def = GraphicsDef(GraphicsType::TILE);
def.path = String("image.png");
def.layer = 2;

auto gfx = GraphicsComponent(def);

As you can see, the graphics component constructor takes a graphics definition as a parameter. A graphics definition, like all other definitions, is a Plain Old Data (POD) structure, which enables us to use nlohmann macros to quickly define all the functions needed to serialize it. Done. Awesome.

// That's it
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(GraphicsDef, type, path, layer);

CI and automatic deploy

This will blown your mind, because the project now builds automatically, through GitHub actions, for Linux, Window, MacOS, Android, and believe it or not for the web. Indeed, click here and be prepared to say wow. All the credits for this go to the brilliant nCine author: @encelo!

Leave a comment

Log in with itch.io to leave a comment.