NcJump devlog #2

Here I am with another devlog. This week I introduced a camera component, and serialization to load and save to file the state of the game. While the former was pretty easy and straightforward to implement, the latter required introducing a new dependency and various scattered refactorings to pay some technical debt accumulated from the previous development iterations.

The smooth

That was easy. The camera component has two main attributes: the scene root node and the target node. The scene root node is needed because we need to simulate the camera, which means that what we actually transform is the scene root node. In other words, to move the camera in on direction, we translate the scene root node to the opposite of such a direction. The target node is the one the camera should follow. As the target node moves around the scene, the camera is updated to match its coordinates.

The quickest thing to implement a following camera is to just write down something like camera.position = target.position, and while it works it is not the best we could do. A better and nicer approach, which might also prevent motion sickness, is to implement a camera with a smooth movement. This can be done by linearly interpolating the camera and the target position by a small factor at every update of the game.

void Camera::update() {
  float smooth_factor = 0.125f;
  Vec2f smoothed_position = lerp(this->position, target->position, smooth_factor);
  this->position = smoothed_position;

The file

Conversely, this feature required a bit more work. I started by adding @nlohmann’s json as a new dependency of the project for reading and writing to json files. I find it very easy to use in addition to the fact that I already used it for previous projects, like Jamspot: Sokoban. The second step was implementing functions to save certain objects to and load them from file.

void to_json(json& j, const T& t);
void from_json(const json& j, T& t);

The trickiest part was to make sure that all the serializable classes of objects could be default constructed. That means avoiding references as class members and preferring pointers, hence allowing semi-initialized objects while making sure they stay in this state for the shortest period as possible to avoid logic errors or even crashes.

Once all this has been taken care of, I was able to edit the game configuration, the tileset, and the tilemap at runtime, close the game, and re-open it to find everything as I set it before. That is key to work on the levels of the game, which is going to be the next iteration of the ncJump development.


Leave a comment

Log in with to leave a comment.