Skip to content
Martin Cohen edited this page Dec 9, 2016 · 2 revisions

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 layers and masks

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 to LayerMask_Ground.
  • Enemies will have layer set to LayerMask_Enemy. The mask should be set to LayerMask_Ground | LayerMask_Player so the enemies cannot move through walls and players (but can move through other enemies).
  • Players will have layer set to LayerMask_Player. The mask should be set to LayerMask_Ground so the players can move through enemies (they might get hit) but cannot move through walls.

Tiles

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.

Entities

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 with scene_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"

Adding and removing entities:

  • 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.

Moving entities

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 in x axis. Returns true if the entity was moved, false otherwise.
  • scene_entity_move_y(...) - Moves entity in y axis. Returns true if the entity was moved, false otherwise.

Testing collisions

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 in x direction.
  • scene_entity_cast_y(...) - Tests if entity can move in y direction.
Clone this wiki locally