Tilemaps can be a great way to keep track of our game world. While a simple array of tile data at their core, they can be much more than that. Today I will look into the concept of directions in a tilemap, how we can perform local steps between tiles easily, and what more we can do once we are that far.
Recently we have seen how we can create our own types to encapsulate physical concepts such as position, velocity, timespan and more. We developed all the types needed for movement in one and two dimensions, however so far we have not talked about rotation.
Today we will look at how to implement the types necessary to also gain the advantages of type-safety when it comes to the rotation and orientation of an object.
We will consider only the two dimensional case, since it is relatively straight forward. However, a similar approach could be taken in three dimensions as well, though it would significantly complicate the mathematics.
In this recent post we saw how we can represent the physical units of length, speed, acceleration, and time using our own types to only allow for type-safe operations between them, and find errors and bugs at compile time.
Today we will expand these ideas to more than one dimension, with the example of two dimensional types.
As discussed in this post there are some potential advantages in representing physical quantities like position, velocity, and similar in a type-safe way.
Instead of using simple floating point types, we can write our own wrapper types that have semantic meanings like ‘length’, ‘speed’, or ‘time’ and only allow physically correct operations between them.
That is exactly what we will look into here. We will implement the basic types for such a system, and show what operations between them are relevant and well defined.
When developing games, working with positions and velocities, time stamps and time spans and similar physical quantities becomes second nature to us.
I would like to explore how we can represent the physical nature of these values, and their relation to each other in code.
Last week we looked into the concept of object pooling, and how it can be used to increase performance by reusing objects that are expensive to create.
We also implemented a generic static class to make using object pools as simple as possible. Today I want to expand on the topic by showing how we can go even further and completely automate the pooling.
Last week I made an argument for simplicity, for keeping it simple. However, complexity does have its place and there are several good reasons to increase the complexity of a system. One such reason is, if we can make that complexity do work for us.
That is what we will do today.
Every game keeps its game object in one or more simple collections. These are used for enumerating the objects every frame to update and draw them.
If objects need to refer to each other, they can easily store a reference to another object, and access it directly. This becomes more difficult however, when we deal with a multiplayer environment. In that case, each game will have its own set of object references, which will never be the same.
That means that we need another way of identifying objects.
Further, we want this access to be fast. After all, a network server might send a client the message that a certain game object should be deleted. If we then need to iterate over all objects to find the correct one, we could easily bog down the performance of our game. Those CPU cycles could be spent much better on something else.
Lastly, whatever data structure we will design for this has to be able to respond appropriately to objects being deleted. See this post for a discussion of how this can be done for simple lists.
Something that probably every game developer has worked with at one time or another – and some of us might work with it daily – is angles.
Angles are used to represent directions and rotations and especially in 2D they are an easy way of doing so, since only a single number is needed to represent an orientation.
In 3D we need three angles – pitch, yaw and roll -, making it slightly more complicated.
In this post I want to explore the way we represent the concepts of angle, direction, orientation and rotation.