Add 8 layers to collisions
This commit is contained in:
@@ -112,47 +112,6 @@ static void handleTileObjectLayer(BzTileObjectGroup *layer, cute_tiled_layer_t *
|
||||
|
||||
}
|
||||
|
||||
static void updateCollisionMap(BzTileMap *map, i32 startX, i32 startY, i32 endX, i32 endY) {
|
||||
BZ_ASSERT(map->collisionMap);
|
||||
BZ_ASSERT(startX >= 0 && endX <= map->width &&
|
||||
startY >= 0 && endY <= map->height);
|
||||
|
||||
for (i32 y = startY; y < endY; y++) {
|
||||
for (i32 x = startX; x < endX; x++) {
|
||||
map->collisionMap[y * map->width + x] = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Top-most layer takes priority
|
||||
for (i32 i = map->layerCount - 1; i >= 0; i--) {
|
||||
BzTileLayer *layer = map->layers + i;
|
||||
if (!layer->desc.applyColliders) continue;
|
||||
if (!layer->data) continue;
|
||||
if (layer->tilesetIdx == -1) continue;
|
||||
BzTileset *tileset = map->tilesets + layer->tilesetIdx;
|
||||
for (i32 y = startY; y < endY; y++) {
|
||||
for (i32 x = startX; x < endX; x++) {
|
||||
i32 idx = y * map->width + x;
|
||||
if (map->collisionMap[idx]) continue;
|
||||
|
||||
BzTile tile = bzTileLayerGetTile(layer, x, y);
|
||||
BzTileID tileID = bzTilesetGetTileID(tileset, tile);
|
||||
BzTileShape tilesetShape = bzTilesetGetTileCollider(tileset, tileID);
|
||||
if (tilesetShape.type == BZ_TILE_SHAPE_NONE ||
|
||||
tilesetShape.type == BZ_TILE_SHAPE_POINT)
|
||||
continue;
|
||||
|
||||
map->collisionMap[idx] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void createColliders(BzTileMap *map) {
|
||||
map->collisionMap = bzAlloc(map->width * map->height * sizeof(*map->collisionMap));
|
||||
updateCollisionMap(map, 0, 0, map->width, map->height);
|
||||
}
|
||||
|
||||
BzTileMap bzTileMapCreate(const BzTileMapDesc *desc) {
|
||||
BzTileMap map = {.backgroundColor=BLACK};
|
||||
// Auto detect tileset count.
|
||||
@@ -257,8 +216,11 @@ BzTileMap bzTileMapCreate(const BzTileMapDesc *desc) {
|
||||
}
|
||||
cute_tiled_free_map(cuteMap);
|
||||
|
||||
if (desc->generateCollisionMap)
|
||||
createColliders(&map);
|
||||
if (desc->collisionMap) {
|
||||
i32 numBytes = map.width * map.height;
|
||||
map.collisionMap = bzAlloc(numBytes);
|
||||
bzMemSet(map.collisionMap, 0, numBytes);
|
||||
}
|
||||
|
||||
map.isValid = true;
|
||||
return map;
|
||||
@@ -407,7 +369,7 @@ f32 bzTileMapRayCast(BzTileMap *map, Vector2 from, Vector2 to, f32 maxDst, Vecto
|
||||
|
||||
i32 cellX = (i32) from.x;
|
||||
i32 cellY = (i32) from.y;
|
||||
if (bzTileMapHasCollision(map, cellX, cellY)) {
|
||||
if (bzTileMapHasAnyCollision(map, cellX, cellY)) {
|
||||
return 0.0f;
|
||||
}
|
||||
Vector2 rayLength = Vector2Zero();
|
||||
@@ -503,25 +465,61 @@ void bzTileMapDrawCollisions(BzTileMap *map) {
|
||||
}
|
||||
}
|
||||
|
||||
bool bzTileMapHasCollision(BzTileMap *map, i32 x, i32 y) {
|
||||
bool bzTileMapHasAnyCollision(BzTileMap *map, i32 x, i32 y) {
|
||||
if (!map->collisionMap) return false;
|
||||
i32 idx = y * map->width + x;
|
||||
return map->collisionMap[idx];
|
||||
return map->collisionMap[idx] != 0;
|
||||
}
|
||||
void bzTileMapSetCollisions(BzTileMap *map, bool collision, i32 startX, i32 startY, i32 sizeX, i32 sizeY) {
|
||||
bool bzTileMapHasCollision(BzTileMap *map, i32 layer, i32 x, i32 y) {
|
||||
BZ_ASSERT(layer >= 0 && layer < 8);
|
||||
if (!map->collisionMap) return false;
|
||||
i32 idx = y * map->width + x;
|
||||
return (map->collisionMap[idx] & (1 << layer)) != 0;
|
||||
}
|
||||
void bzTileMapSetCollisions(BzTileMap *map, bool collision, i32 layer, i32 startX, i32 startY, i32 sizeX, i32 sizeY) {
|
||||
i32 endX = startX + sizeX;
|
||||
i32 endY = startY + sizeY;
|
||||
BZ_ASSERT(layer >= 0 && layer < 8);
|
||||
BZ_ASSERT(map->collisionMap);
|
||||
BZ_ASSERT(startX >= 0 && endX <= map->width &&
|
||||
startY >= 0 && endY <= map->height);
|
||||
|
||||
for (i32 y = startY; y < endY; y++) {
|
||||
for (i32 x = startX; x < endX; x++) {
|
||||
map->collisionMap[y * map->width + x] = collision;
|
||||
i32 idxOffset = y * map->width + x;
|
||||
u8 *cell = map->collisionMap + idxOffset;
|
||||
if (collision)
|
||||
*cell |= (1 << layer);
|
||||
else
|
||||
*cell &= ~(1 << layer);
|
||||
}
|
||||
}
|
||||
}
|
||||
void bzTileMapUpdateCollisions(BzTileMap *map, i32 x, i32 y, i32 sizeX, i32 sizeY) {
|
||||
if (!map->collisionMap) return;
|
||||
updateCollisionMap(map, x, y, x + sizeX, y + sizeY);
|
||||
void bzTileMapAddLayerCollisions(BzTileMap *map, i32 mapLayer, i32 collLayer) {
|
||||
BZ_ASSERT(map);
|
||||
BZ_ASSERT(mapLayer >= 0 && mapLayer < map->layerCount);
|
||||
BZ_ASSERT(collLayer >= 0 && collLayer < 8);
|
||||
|
||||
const i32 layerBit = (1 << collLayer);
|
||||
|
||||
BzTileLayer *layer = map->layers + mapLayer;
|
||||
BzTileset *tileset = map->tilesets + layer->tilesetIdx;
|
||||
for (i32 y = 0; y < map->height; y++) {
|
||||
for (i32 x = 0; x < map->width; x++) {
|
||||
i32 idx = y * map->width + x;
|
||||
if (map->collisionMap[idx]) continue;
|
||||
|
||||
BzTile tile = bzTileLayerGetTile(layer, x, y);
|
||||
BzTileID tileID = bzTilesetGetTileID(tileset, tile);
|
||||
BzTileShape tilesetShape = bzTilesetGetTileCollider(tileset, tileID);
|
||||
u8 *cell = map->collisionMap + idx;
|
||||
if (tilesetShape.type == BZ_TILE_SHAPE_NONE ||
|
||||
tilesetShape.type == BZ_TILE_SHAPE_POINT) {
|
||||
// Reset
|
||||
*cell &= ~layerBit;
|
||||
} else {
|
||||
*cell |= layerBit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ typedef struct BzTileObjectsDesc {
|
||||
|
||||
typedef struct BzTileMapDesc {
|
||||
const char *path;
|
||||
bool generateCollisionMap;
|
||||
bool collisionMap;
|
||||
BzTileset tilesets[BZ_MAP_MAX_TILESETS];
|
||||
|
||||
BzTileLayerDesc layers[BZ_MAP_MAX_LAYERS];
|
||||
@@ -86,7 +86,8 @@ typedef struct BzTileMap {
|
||||
i32 tileWidth;
|
||||
i32 tileHeight;
|
||||
|
||||
bool *collisionMap;
|
||||
u8 *collisionMap;
|
||||
i32 resolution;
|
||||
|
||||
BzTileLayer layers[BZ_MAP_MAX_LAYERS];
|
||||
i32 layerCount;
|
||||
@@ -129,10 +130,12 @@ f32 bzTileMapRayCast(BzTileMap *map, Vector2 from, Vector2 to, f32 maxDst, Vecto
|
||||
bool bzTileMapCanRayCastLine(BzTileMap *map, Vector2 from, Vector2 to);
|
||||
|
||||
void bzTileMapDraw(BzTileMap *map);
|
||||
|
||||
void bzTileMapDrawCollisions(BzTileMap *map);
|
||||
bool bzTileMapHasCollision(BzTileMap *map, i32 x, i32 y);
|
||||
void bzTileMapSetCollisions(BzTileMap *map, bool collision, i32 startX, i32 startY, i32 sizeX, i32 sizeY);
|
||||
void bzTileMapUpdateCollisions(BzTileMap *map, i32 x, i32 y, i32 sizeX, i32 sizeY);
|
||||
bool bzTileMapHasAnyCollision(BzTileMap *map, i32 x, i32 y);
|
||||
bool bzTileMapHasCollision(BzTileMap *map, i32 layer, i32 x, i32 y);
|
||||
void bzTileMapSetCollisions(BzTileMap *map, bool collision, i32 layer, i32 startX, i32 startY, i32 sizeX, i32 sizeY);
|
||||
void bzTileMapAddLayerCollisions(BzTileMap *map, i32 mapLayer, i32 layer);
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user