-
Notifications
You must be signed in to change notification settings - Fork 28
Entities
Punity comes with it's own entity and collision system. The world is held in a Scene
. Each Scene
contains entities and an optional pointer to a TileMap
. Tiles represent static objects, while entities represent movable objects.
You initialize scene like this:
Scene scene;
int spatial_cell_size = 16;
scene_init(&scene, spatial_cell_size);
Collision layer
is a bitfield that identifies group of the same objects. Collision mask
is required for entities to tell with which layers they can collide with. Example:
enum {
// All tiles.
LayerMask_Ground = 1 << 0,
// All players.
LayerMask_Player = 1 << 1,
// All enemies.
LayerMask_Enemy = 1 << 2
}
- Wall tiles will have
layer
set toLayerMask_Ground
. - Enemies will have
layer
set toLayerMask_Enemy
. Themask
should be set toLayerMask_Ground | LayerMask_Player
so the enemies cannot move through walls and players (but can move through other enemies). - Players will have
layer
set toLayerMask_Player
. Themask
should be set toLayerMask_Ground
so the players can move through enemies (they might get hit) but cannot move through walls.
You can use a TileMap
to provide static world colliders. Each Tile
in TileMap
contains a layer
and also lowest 4 bits of flags
are reserved for Edge_*
flags that tell which sides of the tile are collidable. Note that mask
is not needed here, as tiles never move.
Read more about tiles and tilemaps.
SceneEntity
represents an movable entity in the collision system. Entities are internally stored in a SpatialHash
. The hash' cell size can be configured when the scene is initialized with scene_init()
. These are properties of the entity:
-
Rect box
- Entity's rectangle. This is read-only and can be only changed withscene_entity_move_*
functions. -
i32 layer
- Bitfield collision group this entity belongs to (see above). -
i32 mask
- Bifield of collision groups that this entity can collide with (see above).
Note that you can also extend the SceneEntity
struct like this:
#define PUN_SCENE_ENTITY_CUSTOM \
i32 my_custom_field; \
i32 my_other_custom_field;
...
#include "punity.h"
-
Entity *scene_entity_add(...)
- Adds a new entity to the scene and returns pointer to it (instances are kept internally). -
void scene_entity_remove(...)
- Removes existing entity from the scene, so it's pointer is no longer valid.
Each move function requires a Collision
struct to be passed to it by pointer. This struct is filled with useful collision data in case a collision occurs (function returns false
if it does).
-
scene_entity_move_x(...)
- Moves entity inx
axis. Returnstrue
if the entity was moved,false
otherwise. -
scene_entity_move_y(...)
- Moves entity iny
axis. Returnstrue
if the entity was moved,false
otherwise.
You can also just test for collision without moving entities with following two functions. Again the details about collision are returned via a pointer to Collision
struct.
-
scene_entity_cast_x(...)
- Tests if entity can move inx
direction. -
scene_entity_cast_y(...)
- Tests if entity can move iny
direction.