Update 'Step 3: Crates and Entity-Entity Collision'
parent
49f7d01ae2
commit
0506807ec6
|
@ -1 +1,60 @@
|
||||||
TODO: Write about crates
|
Now that the player is ready and can move about with tiles, it's time to add a new entity to interact with: crates.
|
||||||
|
|
||||||
|
Crates are pretty much the building block of the original game. Most other items are contained with crates (or containers) for the player to interact with. I thought this would the best way to begin implementing entity-to-entity collision handling.
|
||||||
|
|
||||||
|
# Crates
|
||||||
|
Crates itself isn't the hardest to implement. By right, crates would have the expected components and the systems written thus far should able to handle its collision and movement. However, crates (and some other items later on) are meant to contain another entity to spawn. Thus, a new component is created to handle this behaviour down the line.
|
||||||
|
```c
|
||||||
|
typedef enum ContainerItem
|
||||||
|
{
|
||||||
|
CONTAINER_EMPTY,
|
||||||
|
CONTAINER_LEFT_ARROW,
|
||||||
|
CONTAINER_RIGHT_ARROW,
|
||||||
|
CONTAINER_UP_ARROW,
|
||||||
|
CONTAINER_DOWN_ARROW,
|
||||||
|
CONTAINER_COIN,
|
||||||
|
CONTAINER_BOMB,
|
||||||
|
}ContainerItem_t;
|
||||||
|
|
||||||
|
typedef enum ContainerMaterial
|
||||||
|
{
|
||||||
|
WOODEN_CONTAINER,
|
||||||
|
METAL_CONTAINER,
|
||||||
|
}ContainerMaterial_t;
|
||||||
|
|
||||||
|
typedef struct _CContainer_t
|
||||||
|
{
|
||||||
|
ContainerMaterial_t material;
|
||||||
|
ContainerItem_t item;
|
||||||
|
}CContainer_t;
|
||||||
|
```
|
||||||
|
In the original game, there are two types of crates: wooden and metal. Furthermore, a container can only contain a selection of items as seen above. This is a small peek on the entities that are going to be implemented later on.
|
||||||
|
# Collision System Part II
|
||||||
|
Previously, the collision system has to deal with tiles only, which are static in the tilemap system. Now, the collision system need to handle dynamic entities. Thankfully, I have already implemented a broad-phase collision detection to help culling out unnecessary collision check. The narrow phase collision should also work given that all entities are also AABB.
|
||||||
|
|
||||||
|
However, there are some things that were considered during the design:
|
||||||
|
- Not all entities will push other entities away. Sometimes, it is okay for entities to overlap.
|
||||||
|
- Other than handling overlap, entity-entity collision will need to interact with each other. This interaction varies between different pairs of entities.
|
||||||
|
- When handling collision events, duplicate events should be skipped or prevented
|
||||||
|
|
||||||
|
To address the first point, a new field is added to the bbox component - a 'solid' field to indicate that overlap in collision is allowed or not. Effectively, a non-solid bbox will not move other entities on collision.
|
||||||
|
|
||||||
|
## Collision Event Resolution
|
||||||
|
To address the second point, I've opt to collection all collision events during the collision detection phase. First, overlapping collisions are resolved alongside the detection. After that, all collision events are resolved one-by-one. This method keeps a clear line in the order of resolution, rather than mixing the different resolutions with the detection step.
|
||||||
|
|
||||||
|
To collect collision event, I need to encode the collision information for processing later. Currently, I've thought of these information that may be important:
|
||||||
|
- The pair of entities colliding
|
||||||
|
- The direction and magnitude of the overlap
|
||||||
|
I've decided to use a int-to-int map to store the collision event. There are alternatives to handling this, but somehow map makes the most sense to me at this point of time. Anyways, to make this work I would need to encode the information I want to keys and values for the map. This is want I settled on:
|
||||||
|
- The colliding pair is encoded as the key as a 32-bit integer. The most significant 16 bits is the current entity index and the least significant bits is the other entity index in the current. This method of encoding means that there is a theoretical entity limit of 65535. However, I do not see the need for such a high entity number for this small game.
|
||||||
|
- The collision overlap is encoded into a 16 bit integer value, associated to the colliding pair key. The most significant 2 bits encodes the direction of collision. This is fine as there is only 4 possible directions in AABB collisions: up, down, left, right. The remaining 14 bits are to encode the magnitude of overlap. This gives a maximum overlap value of 16383, which is more than enough.
|
||||||
|
### Alternative Storage
|
||||||
|
Of course, the above method can be implemented differently. After reviewing the data, it is possible to encode the entire information into a singular 64 bits integer. Then, either a vector or a queue data structure can be used to store the data. For readability, a struct with bit fields (or just regular fileds) can be used as well. In this case, the vector data structure should be used.
|
||||||
|
## Reduce Duplicate Collision
|
||||||
|
Thus far, there is not a way to detect if a pair of entity has been checked. Two measures has been implemented to deal with this:
|
||||||
|
- Every entity has a tag. One way to prevent duplicate collisions is to only allow one-way collision based on the tag. As the tag is essentially an integer, we will only check for collision if the current entity tag is lower or equal to the other entity tag. This way, the tag is used as a priority in collision detection.
|
||||||
|
- A bool array is used to check if an entity has already been checked against. This array is refreshed for each loop through an entity.
|
||||||
|
These two methods does not completely remove duplicate collisions. However, it works good enough. This topic will be revised if needed.
|
||||||
|
|
||||||
|
# Crate Bashing
|
||||||
|
TODO: Write about collision resolution between crates and player
|
Loading…
Reference in New Issue